👏

Pythonでカスタムファイルシステムを作ろう

Pythonでカスタムファイルシステムを作ろう

Pythonでカスタムファイルシステムを作ろう

プログラマーのみなさん、こんにちは!今回はPythonでオレオレファイルシステムを作っているお話です。さっそくコードをご紹介しますね。

コードはcoloramaを使用して色づけし、フォーマットも適切に行っています。こちらが該当部分です。

def fuse_method(f):
    def wrapped_func(*args, **kw):
        try:
            return f(*args, **kw)
        except:
            error('Unhandled error')
    return wrapped_func

def error(*args, **kw):
    from traceback import format_exc
    print(f'{Fore.RED}ERRO{Fore.RESET}', *args, *kw)
    for line in format_exc().splitlines():
        print(f'{Fore.RED}   *{Fore.RESET}', line)

def warn(*args, **kw):
    print(f'{Fore.YELLOW}WARN{Fore.RESET}', *args, *kw)

def info(*args, **kw):
    print(f'{Fore.GREEN}INFO{Fore.RESET}', *args, *kw)

def debug(*args, **kw):
    print(f'{Fore.***}DEBG{Fore.RESET}', *args, *kw)

このコードを使えば、自動的にログが出力されます。便利ですよね!

さらに、以下のように使うことで自動的にログを吐いてくれます。

class OreOreFS(Fuse):
    ...
    @fuse_method
    def readlink(self, path):
        ....

このように使うと、ログ出力が自動的に行われます。とても便利ですよね。

オレオレファイルシステムって何?と思った方もいるかもしれませんね。実は、私は一からファイルシステムを作ったことはないのですが、いろんなWebサービスをファイルシステムにマウントできるフィルタドライバは結構作った経験があります。特にWindowsでの開発では、WebDAVリダイレクタを作るだけでWebサービスをファイルシステムにマウントすることができます。

ただし、WindowsのWebDAVは実装がまともにされていないため、WebDAVリダイレクタを作成するだけで実現できるのは理想的ですが、現実は少し違うようです。

Windowsの開発では、WSLで開発するか、Dokanを使用することが多いです。Dokanを使用すれば、FUSEを開発するよりも容易にファイルシステムを作成することができます。

FUSEの開発はとても楽しいですが、注意が必要です。油断するとカーネルを壊してしまうこともあるため、注意が必要です。

また、今回はPythonのライブラリであるpython-fuseを使用しています。詳しい実装例は、以下のリンクをご参考ください。

python-fuseのサンプルコード

あと、ちなみに本来はpyfuseを使用したかったのですが、Gentoo(Portage)には存在せず、断念しました。Gentooマシンで使用することを想定しているため、別の方法を見つける必要がありました。

FUSEはDokanが全盛期の頃に、結構使っていたので、短期間でリハビリすることができそうです。また、言語バインディングも利用できます。

それでは、次に話題をオレオレファイルシステムに戻します。

オレオレファイルシステムについてもっと詳しく知りたいですよね。では、どうぞ。

オレオレファイルシステムとは、私が考えた最強のファイルシステムです。もちろん、一から作ることはありませんが、Webサービスをファイルシステムにマウントすることができるフィルタドライバのようなものです。Windowsでは特に、いくつかのWebサービスをファイルシステムにマウントできるようなドライバを作成しました。ただし、これらのドライバはハードウェアからのデータをマウントするため、いろいろな問題が発生するかもしれません。

また、ESP32のBLE LL周りのテストが非常に面倒だったため、ファイルシステムにすることも考えました。EEPROMなどでアクセスできるかもしれませんが、実際に使ったことはありません。ブロック単位で指定する必要があるため、非常に面倒です。ブロックデバイスのようになっていれば、使えるかもしれません。

私はハードウェアに直接コマンドを送信することが好きなので、ハードウェアドライバの高水準な実装にはあまり詳しくありません。I2Cならすばやくコマンドを送信できます。以前、遊びで買ったハードウェアを以下にリンクしておきます。

Devantech USB to I2Cモジュール

このデバイスは、USBを介してさまざまなハードウェアを制御することができます。

FUSEを使用してファイルシステムを作る際には、パーミッションチェックが自動的に行われないことがあります。ですが、access(2)のコードを確認することで解決策を見つけることができます。

また、ライブリローディングもしたいと思ったのですが、python-fuseではスレッドループから抜ける方法がなかったため、力ずくで解決しました。後で削除するつもりですので、あまり気に

Nicosys Tech blog

Discussion