Esempio n. 1
0
def main():
    """ fuse mount """
    options = parse_args()
    global USE_APPSTREAM
    USE_APPSTREAM = not options.no_appstream

    init_logging(options.debug)
    fuse_options = set(pyfuse3.default_options)
    if options.debug_fuse:
        fuse_options.add('debug')
    options.mountpoint = Path(options.mountpoint).resolve()
    options.mountpoint.mkdir(parents=True, exist_ok=True)

    virtual_fs = AlpmFs(path=str(options.mountpoint))
    pyfuse3.init(virtual_fs, str(options.mountpoint), fuse_options)
    try:
        trio.run(pyfuse3.main)
    except KeyboardInterrupt:
        print(f"\n\nfusermount -u {options.mountpoint}\n")
    except:
        pyfuse3.close(unmount=True)
        print(f"\n\nfusermount -u {options.mountpoint} ok\n")
        raise

    pyfuse3.close(unmount=True)
Esempio n. 2
0
    def start(self):
        """Starts a pyfuse3 filesystem with different options.

        Raises
        ------
        FUSEError
            If a FUSEError occurs it will close the pyfuse3 filesystem
        """

        fuse_log = _logging.create_logger("pyfuse3", self.fs.debug)
        fuse_options = set(pyfuse3.default_options)
        fuse_options.add('fsname=' + self.fs.__class__.__name__)
        if self.fs.debug:
            fuse_options.add('debug')
        pyfuse3.init(self.fs, self.fs.mount_point, fuse_options)
        try:
            trio.run(pyfuse3.main)
        except FUSEError:
            fuse_log.warning("FUSEError occured")
            pyfuse3.close(unmount=False)
        except Exception as e:
            fuse_log.error("[%s]: %s", type(e).__name__, e)
            pyfuse3.close(unmount=False)
        except BaseException as be:
            fuse_log.error(be.__name__)
            fuse_log.error(be.args)
            fuse_log.error("BaseException occured")
            pyfuse3.close(unmount=False)
        finally:
            pyfuse3.close()
Esempio n. 3
0
def main():
    options = parse_args(sys.argv[1:])
    init_logging(options.debug)
    operations = Operations(options.source)

    log.debug('Mounting...')
    fuse_options = set(pyfuse3.default_options)
    fuse_options.add('fsname=passthroughfs')

    fuse_options.add('allow_other')

    if options.debug_fuse:
        fuse_options.add('debug')

    fuse_options.discard('default_permissions')
    pyfuse3.init(operations, options.mountpoint, fuse_options)

    try:
        log.debug('Entering main loop..')
        trio.run(pyfuse3.main)
    except:
        pyfuse3.close(unmount=False)
        raise

    log.debug('Unmounting..')
    pyfuse3.close()
Esempio n. 4
0
async def main(swhids: List[CoreSWHID], root_path: Path,
               conf: Dict[str, Any]) -> None:
    """ swh-fuse CLI entry-point """

    # Use pyfuse3 asyncio layer to match the rest of Software Heritage codebase
    pyfuse3_asyncio.enable()

    async with FuseCache(conf["cache"]) as cache:
        fs = Fuse(root_path, cache, conf)

        # Initially populate the cache
        for swhid in swhids:
            try:
                await fs.get_metadata(swhid)
            except Exception as err:
                fs.logger.exception("Cannot prefetch object %s: %s", swhid,
                                    err)

        fuse_options = set(pyfuse3.default_options)
        fuse_options.add("fsname=swhfs")

        try:
            pyfuse3.init(fs, root_path, fuse_options)
            await pyfuse3.main()
        except Exception as err:
            fs.logger.error("Error running FUSE: %s", err)
        finally:
            fs.shutdown()
            pyfuse3.close(unmount=True)
Esempio n. 5
0
def run_fuse_mount(ops, options, mount_opts):
    '''Performs FUSE mount'''
    mount_opts = ['fsname=gridfs'] + mount_opts
    opts = dict((opt.split('=', 1) if '=' in opt else (opt, None)
                 for opt in mount_opts))

    # strip invalid keys
    ignored_keys = [
        'debug', 'foreground', 'log_level', 'log_file', 'workers', 'single'
    ]
    valid_keys = [k for k in opts if k not in ignored_keys]
    mount_opts = set(pyfuse3.default_options)
    for k in valid_keys:
        if opts[k] is not None:
            mount_opts.add('='.join([k, opts[k]]))
        else:
            mount_opts.add(k)

    # handle some key options here
    if 'log_level' in opts:
        try:
            log_level = opts['log_level'].upper()
            try:
                log_level = int(log_level)
            except ValueError:
                pass
            logging.getLogger().setLevel(getattr(logging, log_level))
        except (TypeError, ValueError) as error:
            logging.warning('Unable to set log_level to {}: {}'.format(
                opts['log_level'], error))

    # start gridfs bindings and run fuse process
    pyfuse3.init(ops, options.mount_point, mount_opts)

    # ensure that is single is given then it evaluates to true
    if 'single' in opts and opts['single'] is None:
        opts['single'] = True

    # debug clobbers other log settings such as log_level
    if 'debug' in opts:
        logging.basicConfig(
            format=
            '[%(asctime)s] pid=%(process)s {%(module)s:%(funcName)s():%(lineno)d} %(levelname)s - %(message)s',
            level=logging.DEBUG)

    # TODO: Find way of capturing CTRL+C and calling pyfuse3.close() when in foreground
    # Note: This maybe a bug in pyfuse3
    workers = opts.get('workers',
                       opts.get('single',
                                1))  # fudge for backwards compatibility
    try:
        trio.run(
            pyfuse3.main)  # maintain compatibility with single/workers kwarg
    except KeyboardInterrupt:
        pass
    finally:
        pyfuse3.close()
Esempio n. 6
0
def main():
    # parse command line ###
    parser = argparse.ArgumentParser()
    parser.add_argument('source', type=str)
    parser.add_argument('mountpoint', type=str)
    parser.add_argument('--debug', action='store_true')
    parser.add_argument('--logfile', type=str)
    args = parser.parse_args()

    # initialize logger ###
    dbglogformatter = logging.Formatter()
    dbgloghandler = logging.StreamHandler()
    dbgloghandler.setFormatter(dbglogformatter)
    dbglog.addHandler(dbgloghandler)
    if args.debug:
        dbglog.setLevel(logging.DEBUG)
    else:
        dbglog.setLevel(logging.INFO)
    acslog.setLevel(logging.INFO)
    acsformatter = logging.Formatter()
    acshandler = logging.StreamHandler(sys.stdout)
    acshandler.setFormatter(acsformatter)
    acslog.addHandler(acshandler)

    # check arguments
    if not os.path.isdir(args.source):
        dbglog.error('Given source path <{}> is not valid directory.'.format(
            args.source))
        sys.exit(1)
    if not os.path.isdir(args.mountpoint):
        dbglog.error(
            'Given mountpoint path <{}> is not valid directory'.format(
                args.mountpoint))
        sys.exit(1)

    # setting process environment
    os.umask(0)  # to respect file permission which user specified

    # start filesystem ###
    fsops = fusefs.Fusebox(os.path.abspath(args.source),
                           os.path.abspath(args.mountpoint))
    fuse_options = set(pyfuse3.default_options)
    fuse_options.add('fsname=fusefs')
    if args.debug:
        fuse_options.add('debug')
    fuse_options.add('dev')
    fuse_options.add('allow_other')
    pyfuse3.init(fsops, args.mountpoint, fuse_options)
    try:
        trio.run(pyfuse3.main)
    finally:
        pyfuse3.close(unmount=True)

    if args.logfile:
        export_logfile(fsops, args.logfile)

    sys.exit(0)
Esempio n. 7
0
async def mount(client,
                id,
                destination: str,
                offset_id=0,
                limit=None,
                filter_music=False,
                debug_fuse=False,
                reverse=False,
                updates=False,
                fsname="tgfs"):
    pyfuse3_asyncio.enable()
    fuse_options = set(pyfuse3.default_options)
    fuse_options.add('fsname=' + fsname)

    if debug_fuse:
        fuse_options.add('debug')

    # in order to use numeric id
    if isinstance(id, int):
        await client.get_dialogs()

    logging.debug("Querying entity %s" % id)

    entity: Entity = await client.get_entity(id)

    logging.debug("Got '%s'" % get_display_name(entity))

    logging.info(
        "Querying %s messages starting with message_id %d, music: %s" %
        (limit if limit else "all", offset_id, filter_music))

    messages, documents_handles = await client.get_documents(
        entity,
        limit=limit,
        filter_music=filter_music,
        offset_id=offset_id,
        reverse=reverse)

    logging.info("Mounting %d files to %s" %
                 (len(documents_handles), destination))
    # logging.debug("Files: %s" % ([doc['id'] for msg, doc in documents], ))

    telegram_fs = TelegramFsAsync()

    for msg, dh in zip(messages, documents_handles):
        telegram_fs.add_file(msg, dh)

    if updates:
        client.add_event_handler(
            create_new_files_handler(client, telegram_fs, entity), )

    pyfuse3.init(telegram_fs, destination, fuse_options)

    await pyfuse3.main(min_tasks=10)
Esempio n. 8
0
def start_charybdisfs(source: str,  # noqa: C901  # ignore "is too complex" message
                      target: str,
                      debug: bool,
                      rest_api: bool,
                      rest_api_port: int,
                      mount: bool,
                      static_enospc: bool,
                      static_enospc_probability: float) -> None:
    logging.basicConfig(stream=sys.stdout, level=logging.DEBUG if debug else logging.INFO, format=LOG_FORMAT)

    if not rest_api and not mount:
        raise click.UsageError(message="can't run --no-rest-api and --no-mount simultaneously")

    if debug:
        sys.addaudithook(sys_audit_hook)

    if static_enospc:
        static_enospc_probability = max(0, min(100, round(static_enospc_probability * 100)))
        LOGGER.info("Going to add ENOSPC fault for all syscalls with probability %s%%", static_enospc_probability)
        enospc_fault = ErrorFault(sys_call=SysCall.ALL, probability=static_enospc_probability, error_no=errno.ENOSPC)
        Configuration.add_fault(fault_id=generate_fault_id(), fault=enospc_fault)
        LOGGER.debug("Faults added: %s", Configuration.get_all_faults())

    if rest_api:
        api_server_thread = \
            threading.Thread(target=start_charybdisfs_api_server,
                             kwargs={"port": rest_api_port, },
                             name="RestServerApi",
                             daemon=True)
        api_server_thread.start()
        atexit.register(stop_charybdisfs_api_server)

    if mount:
        if source is None or target is None:
            raise click.BadArgumentUsage("both source and target parameters are required for CharybdisFS mount")

        fuse_options = set(pyfuse3.default_options)
        fuse_options.add("fsname=charybdisfs")
        if debug:
            fuse_options.add("debug")

        operations = CharybdisOperations(source=source)

        pyfuse3.init(operations, target, fuse_options)
        atexit.register(pyfuse3.close)

    try:
        if mount:
            trio.run(pyfuse3.main)
        else:
            api_server_thread.join()
    except KeyboardInterrupt:
        LOGGER.info("Interrupted by user...")
        sys.exit(0)
Esempio n. 9
0
def _main():

    # Parse the arguments
    mountpoint, conf, foreground = parse_options()

    LOG.info('Mountpoint: %s', mountpoint)

    # Required configurations
    rootdir = conf.get('DEFAULT', 'rootdir')
    if not rootdir:
        raise ValueError('Missing rootdir configuration')
    rootdir = os.path.expanduser(rootdir)
    if not os.path.exists(rootdir):
        raise ValueError(f'Rootdir {rootdir} does not exist')
    LOG.info('Root dir: %s', rootdir)

    # Encryption/Decryption keys
    seckey = retrieve_secret_key(conf)
    recipients = list(set(build_recipients(conf, seckey))) # remove duplicates
    # recipients might be empty if we don't create files

    # Default configurations
    options = conf.getset('FUSE', 'options', fallback='ro,default_permissions')
    LOG.debug('mount options: %s', options)

    cache_directories = conf.getboolean('FUSE', 'cache_directories', fallback=True)
    extension = conf.get('DEFAULT', 'extension', fallback='.c4gh')

    # Build the file system
    fs = Crypt4ghFS(rootdir, seckey, recipients, extension, cache_directories)
    pyfuse3.init(fs, mountpoint, options)

    if not foreground:
        LOG.info('Running current process in background')
        detach() # daemonize

    try:
        LOG.debug('Entering main loop')
        trio.run(pyfuse3.main)
        # This is an infinite loop.
        # Ctrl-C / KeyboardInterrupt will be propagated (properly?)
        # - https://trio.readthedocs.io/en/stable/reference-core.html
        # - https://vorpus.org/blog/control-c-handling-in-python-and-trio/
    except Exception as e:
        LOG.debug("%r", e)
        raise
    finally:
        LOG.debug('Unmounting')
        pyfuse3.close(unmount=True)

    # The proper way to exit is to call:
    # umount <the-mountpoint>
    return 0
def main(mountpoint, root):
    passt = Passthrough(root)
    fuse_options = set()
    fuse_options.add('fsname=passthroughfs')
    fuse_options.add('allow_other')
    
    
    try:
        pyfuse3.init(passt,mountpoint,fuse_options)
        trio.run(pyfuse3.main)
    except:
        pyfuse3.close(unmount=False)
        raise
Esempio n. 11
0
def start_charybdisfs(source: str, target: str, debug: bool) -> None:
    operations = CharybdisOperations(source=source)

    fuse_options = set(pyfuse3.default_options)
    fuse_options.add("fsname=charybdisfs")
    if debug:
        fuse_options.add("debug")

    pyfuse3.init(operations, target, fuse_options)
    try:
        trio.run(pyfuse3.main)
    except:
        pyfuse3.close(unmount=False)
        raise
    pyfuse3.close()
Esempio n. 12
0
def main():
    parser = argparse.ArgumentParser(description='Mount a FapTrack filesystem')
    parser.add_argument('mountpoint', type=str, help='the mountpoint')
    args = parser.parse_args()

    my_opts = set(pyfuse3.default_options)
    my_opts.add('allow_root')
    my_opts.discard('default_permissions')
    pyfuse3.init(VirtualFS(trackFS), args.mountpoint, my_opts)
    try:
        trio.run(pyfuse3.main)
    except:
        pyfuse3.close()
        raise

    pyfuse3.close()
Esempio n. 13
0
def main():
    options = parse_args()
    init_logging(options.debug)

    testfs = ADfs()
    fuse_options = set(pyfuse3.default_options)
    fuse_options.add('fsname=ad')
    if options.debug_fuse:
        fuse_options.add('debug')
    pyfuse3.init(testfs, options.mountpoint, fuse_options)
    try:
        trio.run(pyfuse3.main)
    except:
        pyfuse3.close(unmount=False)
        raise

    pyfuse3.close()
Esempio n. 14
0
def main():
    parser = argparse.ArgumentParser(
        description='Mount a FapTrack filesystem',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('mountpoint', type=str, help='the mountpoint')
    parser.add_argument('--database',
                        '-d',
                        type=str,
                        help='the sqlite3 database file',
                        default='faptrack.db')
    parser.add_argument('--max_view_time',
                        '-m',
                        type=int,
                        help='the max view time to be recorded',
                        default=15 * 60)
    parser.add_argument('--logging',
                        '-l',
                        type=str,
                        choices=logging._nameToLevel.keys(),
                        default="WARNING",
                        help='the logging level')

    args = parser.parse_args()

    logging.basicConfig(format='%(asctime)s %(message)s',
                        level=logging._nameToLevel[args.logging])

    my_opts = set(pyfuse3.default_options)
    my_opts.add('allow_root')
    my_opts.discard('default_permissions')

    def conn_fac():
        return sqlite3.connect(args.database)

    pyfuse3.init(VirtualFS(trackFS(conn_fac, args.max_view_time * (10**9))),
                 args.mountpoint, my_opts)
    try:
        asyncio.run(pyfuse3.main())
    except:
        pyfuse3.close()
        raise

    pyfuse3.close()
Esempio n. 15
0
    async def _go(self):
        fuse_options = set(pyfuse3.default_options)
        fuse_options.add('fsname=infofs')
        if self.debug:
            fuse_options.add('debug')
        pyfuse3.init(self, str(self.mountpoint), fuse_options)

        try:
            async with trio.open_nursery() as nursery:
                nursery.start_soon(pyfuse3.main)
                for command_spec in self.commands:
                    nursery.start_soon(self._scheduler,
                                       bytes(command_spec.name,
                                             'utf-8'), command_spec.command,
                                       command_spec.delay, nursery)
        except:
            raise
        finally:
            pyfuse3.close()
Esempio n. 16
0
def start_charybdisfs(source: str, target: str, debug: bool,
                      enospc_probability) -> None:
    logging.basicConfig()

    operations = CharybdisOperations(source=source,
                                     enospc_probability=enospc_probability)

    fuse_options = set(pyfuse3.default_options)
    fuse_options.add("fsname=charybdisfs")
    if debug:
        fuse_options.add("debug")

    pyfuse3.init(operations, target, fuse_options)
    try:
        trio.run(pyfuse3.main)
    except:
        pyfuse3.close(unmount=False)
        raise
    pyfuse3.close()
Esempio n. 17
0
def main():
    parser = argparse.ArgumentParser(description='Mount a FapTrack filesystem')
    parser.add_argument('mountpoint', type=str, help='the mountpoint')
    parser.add_argument('--database', '-d', type=str, help='the sqlite3 database file', default='faptrack.db')
    args = parser.parse_args()
    
    my_opts = set(pyfuse3.default_options)
    my_opts.add('allow_root')
    my_opts.discard('default_permissions')

    def conn_fac():
        return sqlite3.connect(args.database)
    pyfuse3.init(VirtualFS(trackFS(conn_fac)), args.mountpoint, my_opts)
    try:
        trio.run(pyfuse3.main)
    except:
        pyfuse3.close()
        raise

    pyfuse3.close()
Esempio n. 18
0
def main():
    options = parse_args()
    init_logging(options.debug)

    testfs = TestFs()
    fuse_options = set(pyfuse3.default_options)
    fuse_options.add('fsname=hello_asyncio')
    if options.debug_fuse:
        fuse_options.add('debug')
    pyfuse3.init(testfs, options.mountpoint, fuse_options)
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(pyfuse3.main())
    except:
        pyfuse3.close(unmount=False)
        raise
    finally:
        loop.close()

    pyfuse3.close()
Esempio n. 19
0
def main():
    options = parse_args(sys.argv[1:])
    init_logging(options.debug)
    operations = Operations(options.source)

    log.debug('Mounting...')
    fuse_options = set(pyfuse3.default_options)
    fuse_options.add('fsname=securepassthroughfs')
    if options.debug_fuse:
        fuse_options.add('debug')
    pyfuse3.init(operations, options.mountpoint, fuse_options)

    try:
        log.debug('Entering main loop..')
        log.debug('Use fusermount3 -u ' + options.mountpoint + " to umount")
        trio.run(pyfuse3.main)
        #t.join()
    except:
        pyfuse3.close(unmount=True)
        raise
Esempio n. 20
0
def run_fs(mountpoint, cross_process):
    # Logging (note that we run in a new process, so we can't
    # rely on direct log capture and instead print to stdout)
    root_logger = logging.getLogger()
    formatter = logging.Formatter('%(asctime)s.%(msecs)03d %(levelname)s '
                                  '%(funcName)s(%(threadName)s): %(message)s',
                                   datefmt="%M:%S")
    handler = logging.StreamHandler(sys.stdout)
    handler.setLevel(logging.DEBUG)
    handler.setFormatter(formatter)
    root_logger.addHandler(handler)
    root_logger.setLevel(logging.DEBUG)

    testfs = Fs(cross_process)
    fuse_options = set(pyfuse3.default_options)
    fuse_options.add('fsname=pyfuse3_testfs')
    pyfuse3.init(testfs, mountpoint, fuse_options)
    try:
        trio.run(pyfuse3.main)
    finally:
        pyfuse3.close()
Esempio n. 21
0
def main():
    args = parse_args()

    pngfs = pngFS(args)

    fuse_options = set(pyfuse3.default_options)
    fuse_options.add('fsname=pngFS')
    if args.fuse_debug:
        fuse_options.add('debug')

    pyfuse3.init(pngfs, args.mountpoint, fuse_options)

    try:
        asyncio.run(pyfuse3.main())
    except KeyboardInterrupt:
        pass

    pngfs.files.clean_files_without_parent()
    pngfs.write_to_png()

    pyfuse3.close()
Esempio n. 22
0
def main():
    options = parse_args()
    init_logging(options.debug)

    testfs = TestFs()
    fuse_options = set(pyfuse3.default_options)
    fuse_options.add('fsname=hello')
    if options.debug_fuse:
        fuse_options.add('debug')
    pyfuse3.init(testfs, options.mountpoint, fuse_options)
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(pyfuse3.main())
    except:
        print("Encountered error so will try to unmount")
        pyfuse3.close(unmount=True)
        raise
    else:
        print("Unmounted: exiting cleanly with out further unmount")
        pyfuse3.close(unmount=False)
    finally:
        loop.close()
Esempio n. 23
0
def mount_fuse(source, mountpoint):
    init_logging()  # Nod debug for now
    operations = Operations(str(source))

    log.debug('Mounting...')
    fuse_options = set(pyfuse3.default_options)
    fuse_options.add('fsname=zisofuse')
    # if options.debug_fuse:
    #     fuse_options.add('debug')
    pyfuse3.init(operations, str(mountpoint), fuse_options)

    try:
        log.debug('Entering main loop..')
        trio.run(pyfuse3.main)
    except KeyboardInterrupt:
        pyfuse3.close(unmount=True)
        return
    except:
        pyfuse3.close(unmount=True)
        raise

    log.debug('Unmounting..')
    pyfuse3.close()
Esempio n. 24
0
def main():
    logging.basicConfig()
    args = parse_args()
    if args.debug:
        logging.getLogger().setLevel(logging.DEBUG)

    argv = args.argv_prefix if args.argv_prefix else ("bash", "-c")
    operations = BashFS(argv_prefix=argv, separator=args.separator.encode())

    fuse_options = set(pyfuse3.default_options)
    fuse_options.add("fsname=bashfs")
    fuse_options.discard("default_permissions")
    if args.debug_fuse:
        fuse_options.add("debug")
    pyfuse3.init(operations, args.mountpoint, fuse_options)

    try:
        trio.run(pyfuse3.main)
    except:
        pyfuse3.close(unmount=True)
        raise

    pyfuse3.close()
Esempio n. 25
0
def main():
    options = parse_args(sys.argv[1:])
    init_logging(options.debug)
    operations = Operations(options.source)

    log.debug('Mounting...')
    fuse_options = set(pyfuse3.default_options)
    fuse_options.add('fsname=passthroughfs')
    if options.debug_fuse:
        fuse_options.add('debug')
    pyfuse3.init(operations, options.mountpoint, fuse_options)

    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(pyfuse3.main())
    except:
        print("Encountered error so will try to unmount")
        pyfuse3.close(unmount=True)
        raise
    else:
        print("Unmounted: exiting cleanly with out further unmount")
        pyfuse3.close(unmount=False)
    finally:
        loop.close()
Esempio n. 26
0
        root_fs = FS(process_course_configs())
    except Exception as err:
        # We want any exception that is thrown to go through `better_exceptions`, which provides debug information that's **actually useful**
        logger.exception(err)
        raise

    logger.info("canvasfs initialised. Starting filesystem")

    mount_target = Path(config()["mount_dir"])
    mount_target.mkdir(parents=True, exist_ok=True)
    if len(list(mount_target.iterdir())) > 0:
        raise ConfigError(
            "'mount_dir' must be empty, as its contents will be overwritten when mounted"
        )

    pyfuse3.init(root_fs, str(mount_target), fuse_options)

    async def loop():
        # Ensure the files and directories have been fetched from Canvas and setup by the time the filesystem is started
        async with trio.open_nursery() as nursery:
            for _, sub in root_fs:
                nursery.start_soon(sub.build)

        logger.success("Filesystem built. Ready to go!")

        # Background polling to allow periodic refreshes that can be initiated by each SubFS
        async with trio.open_nursery() as nursery:
            nursery.start_soon(pyfuse3.main)

            for _, sub in root_fs:
                nursery.start_soon(sub.poll)
Esempio n. 27
0
def main():
    options = parse_args(sys.argv[1:])
    init_logging(options.debug)

    cache_size = options.cache_size * 1024 * 1024
    degoo_email = options.degoo_email
    degoo_pass = options.degoo_pass
    degoo_token = options.degoo_token
    degoo_refresh_token = options.degoo_refresh_token
    degoo_path = options.degoo_path
    refresh_interval = options.refresh_interval * 60
    disable_refresh = options.disable_refresh
    enable_flood_control = options.enable_flood_control
    change_hostname = options.change_hostname
    mode = options.mode
    config_path = options.config_path

    log.debug('##### Initializating Degoo drive #####')
    log.debug('Local mount point:   %s', options.mountpoint)
    log.debug('Cache size:          %s', str(cache_size) + ' kb')
    if degoo_email and degoo_pass:
        log.debug('Degoo email:         %s', degoo_email)
        log.debug('Degoo pass:          %s', '*' * len(degoo_pass))
    if degoo_token and degoo_refresh_token:
        log.debug('Degoo token:         %s', '*' * len(degoo_token[:10]))
        log.debug('Degoo refresh token: %s',
                  '*' * len(degoo_refresh_token[:10]))
    log.debug('Root Degoo path:     %s', degoo_path)
    log.debug(
        'Refresh interval:    %s',
        'Disabled' if disable_refresh else str(refresh_interval) + ' seconds')
    log.debug('Flood control:       %s',
              'Enabled' if enable_flood_control else 'Disabled')
    if enable_flood_control:
        log.debug('Flood sleep time:    %s seconds',
                  str(options.flood_sleep_time))
        log.debug('Flood max requests:  %s', str(options.flood_max_requests))
        log.debug('Flood time check:    %s minute(s)',
                  str(options.flood_time_to_check))
    log.debug('Change hostname:     %s',
              'Disabled' if not change_hostname else DEGOO_HOSTNAME_EU)
    log.debug('Mode:                %s', mode)
    if config_path:
        log.debug('Configuration path:  %s', config_path)

    if options.allow_other:
        log.debug('User access:         %s', options.allow_other)

    Path(options.mountpoint).mkdir(parents=True, exist_ok=True)

    operations = Operations(source=degoo_path,
                            cache_size=cache_size,
                            flood_sleep_time=options.flood_sleep_time,
                            flood_time_to_check=options.flood_time_to_check,
                            flood_max_requests=options.flood_max_requests,
                            enable_flood_control=enable_flood_control,
                            change_hostname=change_hostname,
                            mode=mode)

    log.debug('Reading Degoo content from directory %s', degoo_path)

    degoo.DegooConfig(config_path,
                      email=degoo_email,
                      password=degoo_pass,
                      token=degoo_token,
                      refresh_token=degoo_refresh_token)
    degoo.API()
    operations.load_degoo_content()

    log.debug('Mounting...')
    fuse_options = set(pyfuse3.default_options)
    fuse_options.add('fsname=fusedegoo')

    if options.allow_other:
        fuse_options.add('allow_other')

    mimetypes.init()
    if options.debug_fuse:
        fuse_options.add('debug')

    pyfuse3.init(operations, options.mountpoint, fuse_options)

    if not disable_refresh:
        t1 = threading.Thread(target=operations.refresh_degoo_content,
                              args=(refresh_interval, ))
        t1.start()

    try:
        log.debug('Entering main loop..')
        trio.run(pyfuse3.main)
    except:
        print('Unexpected error: ', sys.exc_info()[0])
        global is_refresh_enabled
        is_refresh_enabled = False
        pyfuse3.close(unmount=True)
        raise

    log.debug('Unmounting..')
    pyfuse3.close()
Esempio n. 28
0
def main():
    ### parse command line ###
    parser = argparse.ArgumentParser()
    parser.add_argument('--fusebox_debug', action='store_true')
    parser.add_argument('--pyfuse_debug', action='store_true')
    parser.add_argument('command')
    parser.add_argument('command_args', nargs=argparse.REMAINDER)
    #args, cmd = parser.parse_known_args()
    args = parser.parse_args()

    # assemble command and that arguments
    cmd = list()
    cmd.append(args.command)
    cmd.extend(args.command_args)

    ### initialize logger ###
    dbglogformatter = logging.Formatter()
    dbgloghandler = logging.StreamHandler()
    dbgloghandler.setFormatter(dbglogformatter)
    dbglog.addHandler(dbgloghandler)
    if args.fusebox_debug:
        dbglog.setLevel(logging.DEBUG)
    else:
        dbglog.setLevel(logging.INFO)
    acslog.setLevel(logging.INFO)
    acsformatter = logging.Formatter()
    acshandler = logging.StreamHandler(sys.stdout)
    acshandler.setFormatter(acsformatter)
    acslog.addHandler(acshandler)

    # setting process environment
    umask_prev = os.umask(0)  # to respect file permission which user specified

    # initialize filesystem ###
    ctx_mountpoint = tempfile.TemporaryDirectory()
    atexit.register(
        lambda: ctx_mountpoint.cleanup())  # reserve cleanup for mountpoint
    mountpoint = ctx_mountpoint.name
    fsops = fusefs.Fusebox(os.path.abspath('/'), os.path.abspath(mountpoint))
    fsops.auditor.enabled = False
    fuse_options = set(pyfuse3.default_options)
    fuse_options.add('fsname=fusefs')
    if args.pyfuse_debug:
        fuse_options.add('debug')
    fuse_options.add('dev')
    fuse_options.add('allow_other')

    # print current status
    dbglog.info('*** Fusebox Status ***')
    dbglog.info('uid:\t{}'.format(os.getuid()))
    dbglog.info('gid:\t{}'.format(os.getgid()))
    dbglog.info('pid:\t{}'.format(os.getpid()))
    dbglog.info('prev_umask:\t{:04o}'.format(umask_prev))
    dbglog.info('cmd:\t{}'.format(cmd))
    dbglog.info('acl:\t{}'.format(
        'engaged' if fsops.auditor.enabled else 'disengaged'))
    dbglog.info('mount:\t{}'.format(mountpoint))

    # start filesystem
    pyfuse3.init(
        fsops, mountpoint, fuse_options
    )  # From this point, accessing under the mountpoint will be blocked.

    tmp_stdin = os.dup(
        sys.stdin.fileno()
    )  # backup stdin fd. since multiprocessing will override stdin in forked process.
    os.set_inheritable(tmp_stdin,
                       True)  # make sure to keep fd opened in forked process.
    proc_cmd = multiprocessing.Process(target=launcher,
                                       args=(cmd, tmp_stdin, mountpoint))
    proc_fusebox = multiprocessing.Process(target=start_sandbox)
    del tmp_stdin  # forget backuped pipe in parent process as it is not needed.
    proc_cmd.start()
    proc_fusebox.start()

    proc_cmd.join()  # to eliminate zombie process
    proc_cmd.close()
    # given commands are exited.
    pyfuse3.close(unmount=True)  # release unnecessary resource
    proc_fusebox.terminate()  # send exit signal to fuse process
    proc_fusebox.join()
    proc_fusebox.close()
Esempio n. 29
0
File: mount.py Progetto: xlotlu/s3ql
async def main_async(options, stdout_log_handler):

    # Get paths
    cachepath = options.cachepath

    backend_factory = get_backend_factory(options)
    backend_pool = BackendPool(backend_factory)
    atexit.register(backend_pool.flush)

    # Retrieve metadata
    with backend_pool() as backend:
        (param, db) = get_metadata(backend, cachepath)

    #if param['max_obj_size'] < options.min_obj_size:
    #    raise QuietError('Maximum object size must be bigger than minimum object size.',
    #                     exitcode=2)

    # Handle --cachesize
    rec_cachesize = options.max_cache_entries * param['max_obj_size'] / 2
    avail_cache = shutil.disk_usage(os.path.dirname(cachepath))[2] / 1024
    if options.cachesize is None:
        options.cachesize = min(rec_cachesize, 0.8 * avail_cache)
        log.info('Setting cache size to %d MB', options.cachesize / 1024)
    elif options.cachesize > avail_cache:
        log.warning('Requested cache size %d MB, but only %d MB available',
                    options.cachesize / 1024, avail_cache / 1024)

    if options.nfs:
        # NFS may try to look up '..', so we have to speed up this kind of query
        log.info('Creating NFS indices...')
        db.execute(
            'CREATE INDEX IF NOT EXISTS ix_contents_inode ON contents(inode)')

    else:
        db.execute('DROP INDEX IF EXISTS ix_contents_inode')

    metadata_upload_task = MetadataUploadTask(backend_pool, param, db,
                                              options.metadata_upload_interval)
    block_cache = BlockCache(backend_pool, db, cachepath + '-cache',
                             options.cachesize * 1024,
                             options.max_cache_entries)
    commit_task = CommitTask(block_cache)
    operations = fs.Operations(block_cache,
                               db,
                               max_obj_size=param['max_obj_size'],
                               inode_cache=InodeCache(db, param['inode_gen']),
                               upload_event=metadata_upload_task.event)
    block_cache.fs = operations
    metadata_upload_task.fs = operations

    async with trio.open_nursery() as nursery:
        with ExitStack() as cm:
            log.info('Mounting %s at %s...', options.storage_url,
                     options.mountpoint)
            try:
                pyfuse3.init(operations, options.mountpoint,
                             get_fuse_opts(options))
            except RuntimeError as exc:
                raise QuietError(str(exc), exitcode=39)

            unmount_clean = False

            def unmount():
                log.info("Unmounting file system...")
                pyfuse3.close(unmount=unmount_clean)

            cm.callback(unmount)

            if options.fg or options.systemd:
                faulthandler.enable()
                faulthandler.register(signal.SIGUSR1)
            else:
                if stdout_log_handler:
                    logging.getLogger().removeHandler(stdout_log_handler)
                crit_log_fd = os.open(
                    os.path.join(options.cachedir, 'mount.s3ql_crit.log'),
                    flags=os.O_APPEND | os.O_CREAT | os.O_WRONLY,
                    mode=0o644)
                faulthandler.enable(crit_log_fd)
                faulthandler.register(signal.SIGUSR1, file=crit_log_fd)
                daemonize(options.cachedir)

            mark_metadata_dirty(backend, cachepath, param)

            block_cache.init(options.threads)

            nursery.start_soon(metadata_upload_task.run,
                               name='metadata-upload-task')
            cm.callback(metadata_upload_task.stop)

            nursery.start_soon(commit_task.run, name='commit-task')
            cm.callback(commit_task.stop)

            exc_info = setup_exchook()

            if options.systemd:
                import systemd.daemon
                systemd.daemon.notify('READY=1')

            try:
                ret = await pyfuse3.main()
            finally:
                await operations.destroy()
                await block_cache.destroy(options.keep_cache)

            if ret is not None:
                raise RuntimeError('Received signal %d, terminating' % (ret, ))

            # Re-raise if main loop terminated due to exception in other thread
            if exc_info:
                (exc_inst, exc_tb) = exc_info
                raise exc_inst.with_traceback(exc_tb)

            log.info("FUSE main loop terminated.")

            unmount_clean = True

    # At this point, there should be no other threads left

    # Do not update .params yet, dump_metadata() may fail if the database is
    # corrupted, in which case we want to force an fsck.
    if operations.failsafe:
        log.warning('File system errors encountered, marking for fsck.')
        param['needs_fsck'] = True
    with backend_pool() as backend:
        seq_no = get_seq_no(backend)
        if metadata_upload_task.db_mtime == os.stat(cachepath +
                                                    '.db').st_mtime:
            log.info('File system unchanged, not uploading metadata.')
            del backend['s3ql_seq_no_%d' % param['seq_no']]
            param['seq_no'] -= 1
            save_params(cachepath, param)
        elif seq_no == param['seq_no']:
            param['last-modified'] = time.time()
            dump_and_upload_metadata(backend, db, param)
            save_params(cachepath, param)
        else:
            log.error(
                'Remote metadata is newer than local (%d vs %d), '
                'refusing to overwrite!', seq_no, param['seq_no'])
            log.error(
                'The locally cached metadata will be *lost* the next time the file system '
                'is mounted or checked and has therefore been backed up.')
            for name in (cachepath + '.params', cachepath + '.db'):
                for i in range(4)[::-1]:
                    if os.path.exists(name + '.%d' % i):
                        os.rename(name + '.%d' % i, name + '.%d' % (i + 1))
                os.rename(name, name + '.0')

    log.info('Cleaning up local metadata...')
    db.execute('ANALYZE')
    db.execute('VACUUM')
    db.close()

    log.info('All done.')
Esempio n. 30
0
                        default=False,
                        help='Enable debugging output')
    parser.add_argument('--debug-fuse',
                        action='store_true',
                        default=False,
                        help='Enable FUSE debugging output')

    return parser.parse_args()


if __name__ == '__main__':

    options = parse_args()
    init_logging(options.debug)
    operations = Operations()

    fuse_options = set(pyfuse3.default_options)
    fuse_options.add('fsname=tmpfs')
    fuse_options.discard('default_permissions')
    if options.debug_fuse:
        fuse_options.add('debug')
    pyfuse3.init(operations, options.mountpoint, fuse_options)

    try:
        trio.run(pyfuse3.main)
    except:
        pyfuse3.close(unmount=False)
        raise

    pyfuse3.close()