Code Monkey home page Code Monkey logo

btrview's Introduction

BTRVIEW

Overview:

Call btrview with a label to get an overview of the subvolume and snapshot tree layout for that specified btrfs filesystem. Call it with multiple labels and it will list each filesystem specified. Call it with no labels, and it will give an overview of every btrfs filesystem it can find.

> sudo btrview --labels HDDs --fold 5

btrview output

Subvolumes that are mounted (in fstab or somehow else) are in bold, those that are grey are subvolumes that aren't currently reachable on the filesystem, and subvolumes in red (not shown here) are not currently on the filesytem. This could be because they're deleted, or maybe its child subvolume was btrfs received from another filesystem.

Wondering what the difference between the subvolume and snapshot tree is? Check out the FAQ!

Installation:

Btrview relies on the following dependencies:

The easiest way to download btrview is to use pipx to download it from the python package index. Use the command pipx install --system-site-packages btrview. Using pipx to install btrview will also install treelib and rich and add the btrview command to your path allowing you to run the command from anywhere on the system.

If you don't feel like installing via pipx you can download it via git clone https://github.com/CopOnTheRun/btrview then cd btrview. From within the btrview directory you can run the script with python -m btrview. Note that if you clone the repository you'll need to make sure you have all the dependencies installed already.

Installation Troubleshooting

Q: How come when I use the sudo command with btrview I get sudo: btrview: command not found, but when I run it without sudo the command is recognized?

A: You are likely using a linux distribution which hard codes the paths sudo can use to find executables. There are two options here, you can either comment out the line that contains "secure_path" in /etc/sudoers or you can add the path you're using to that variable. The former option will change it so that any executable in the user's path can be executed, the latter option will merely add the user's path to list of allowed paths.

Some Qs and As:

Q: What is btrfs?

In short, it's a copy on write (COW) filesystem. If you're not already using btrfs, then check out the documentation to see if it's something you'd be interested in.

Q: What does btrview do?

It produces a view of the btrfs filesystems, mounts, as well as the subvolume tree or snapshot tree on your system.

Q: What's the difference between the subvolume tree and the snapshot tree?

The subvolume tree is a tree of which subvolumes are within other subvolumes, parents being denoted by "Parent ID". The subvolume tree can be manipulated by moving subvolumes in or out of other subvolumes. The snapshot tree shows the relations between snapshots, ie snapshots taken of snapshots, etc.

If that's a little obscure here's a visual example of the difference.

If you run these commands:

btrfs subvolume create subvol
btrfs subvolume create subvol/nested_subvol
btrfs subvolume snapshot subvol subvol/subvol-snap
btrfs subvolume snapshot subvol subvol/subvol-snap2
btrfs subvolume snapshot subvol/nested_subvol subvol/nested_subvol-snap

The subvolume tree would look like:

subvol
├── nested_subvol
├── subvol-snap
├── subvol-snap2
└── nested_subvol-snap

The snapshot tree would look like:

subvol
├── subvol-snap
└── subvol-snap2
nested_subvol
└── nested_subvol-snap

Q: What's the point of this program?

The main thing btrview accomplishes is providing an organized overview of a (or multiple) btrfs filesystem(s). Due to the fact btrfs relies only on loose conventions to determine where snapshots are stored, and how subvolumes are organized, it can be difficult to gain an understanding of how things are laid out. With btrview it's easy to know which subvolumes have snapshots, how many, and where they're stored. Even if your snapshots and subvolumes are scattered around a messy filesystem they'll all still show up as a nice little tree.

Q: What's not the point of this program?

This is in no way shape or form a backup solution. Use something like btrbk for that.

This is also not a snapshot diff viewer. If that sounds like something you're interested in check out httm.

To put it plainly, btrview merely shows the state of things as they are, it doesn't actually "do" anything.

Q: How is the "btr" part of btrview pronounced?

The same as the "btr" part of btrfs.

btrview's People

Contributors

copontherun avatar

Stargazers

plops avatar Patryk Kielar avatar Nicolas Vincent avatar Luca Saclet avatar  avatar Leepa avatar Dan Berindei avatar Tony Nguyễn avatar QuanTrieuPCYT avatar Sagar Reddy avatar  avatar Epiq Sty avatar Deniz Sharideh avatar Ikem Krueger avatar Hans Guthrie avatar Ano Rebel avatar George Andrei avatar  avatar Sascha Krusbersky avatar Sergey avatar Erin Watson avatar Joachim Friberg avatar  avatar Braden Farmer avatar Zsolt Donca avatar Marcelo Tondello Castoldi avatar  avatar

Watchers

 avatar Marcelo Tondello Castoldi avatar Walter Rudametkin avatar

btrview's Issues

System cannot find command btrview when running as sudo

I'm having trouble getting started.

My OS is Fedora 39 (KDE spin), and I installed using pip install btrview. When I try running sudo btrview, I get the error sudo: btrview: command not found. However, when I run just btrview, I get something that suggests that I do in fact have this command on my computer.

$ btrview
WARNING: You're current running this script as user erin.
If you have problems, try rerunning this script with sudo, or as the root user.
Traceback (most recent call last):
  File "/home/erin/.local/bin/btrview", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/erin/.local/lib/python3.12/site-packages/btrview/scripts/btrview.py", line 58, in main
    output = logic(args.labels, args.exclude, args.property, 
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/erin/.local/lib/python3.12/site-packages/btrview/rich_output.py", line 140, in logic
    subvols = fs.subvolumes(remove)
              ^^^^^^^^^^^^^^^^^^^^^
  File "/home/erin/.local/lib/python3.12/site-packages/btrview/btrfs.py", line 120, in subvolumes
    subvols = [] if "root" in remove else [Subvolume.from_ID("5",mount_point, self.mounts)]
                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/erin/.local/lib/python3.12/site-packages/btrview/subvolume.py", line 104, in from_ID
    props = cls._run_cmd(cmd)
            ^^^^^^^^^^^^^^^^^
  File "/home/erin/.local/lib/python3.12/site-packages/btrview/subvolume.py", line 122, in _run_cmd
    out = run(cmd)
          ^^^^^^^^
  File "/home/erin/.local/lib/python3.12/site-packages/btrview/utils.py", line 23, in run
    raise e
  File "/home/erin/.local/lib/python3.12/site-packages/btrview/utils.py", line 20, in run
    out = subprocess.run(tokens, check=True, capture_output=True, 
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/subprocess.py", line 571, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['btrfs', 'subvolume', 'show', '-r', '5', '/home']' returned non-zero exit status 1.

Was there an installation step that I missed?

btrview when run with --deleted but without --snapshot, throws an error

This is caused because subvolumes that are deleted don't contain any properties in the .props dictionary except their UUID. So when trying to add to the tree, the id is an empty string. For the first instance of this happening, there is no error thrown because an empty string is actually a valid ID in a a treelib tree. However when the second deleted subvolume gets added to the tree a DuplicatedNodeError gets thrown.

I'm of a couple minds on how to fix this.

  1. The first is to just to disallow the --deleted flag to be passed without the --snapshot flag, unfortunately that doesn't stop anyone who is using btrview as a library from causing the error.
  2. The next, and easiest idea would be to modify Btrfs.forest so that deleted subvolumes are merely ignored when the snapshots parameter in false. This would prevent those using btrview as a library from dealing with this error.
  3. It's also possible that Subvolume.deleted could be checked somewhere deeper in the logic of constructing a tree, but I fear that would get messy.
  4. Long term I might restructure the Subvolume class hierarchy which might end up fixing things if I get lucky? Probably not.

Anyway, things to think about!

Provide way to create a snapshot tree with off-filesystem subvolumes

One of the features of btrfs is the send/receive functionality which transports subvolumes to different filesytems. Currently btrview only works on a per filesystem basis, being able to create a snapshot tree across btrfs file systems could provide better clarity of where and how snapshots are stored.

Off filesystem snapshots fall into two categories:

  • non-networked - other btrfs filesystems that are mounted somewhere on the filesystem. These should be relatively easy to deal with because I already have them when creating snapshot forests. The only thing that really needs to happen is they have to be grouped and fed through Btrfs.get_forest. The hard part will be figuring out how I want to cli output to show this.
  • networked - snapshots that have been sent to other machines, or are connected via a networked filesystem. In theory as long as I can get the output of btrfs subvolume list and btrfs subvolume show on those filesystems I can create the tree, but this won't be super easy as there's probably 100 different ways to do that, all with their own quirks.

<FS_TREE> not being included in the correct snapshot tree when passing certain flags to --include

Not sure what's causing it not to get added to the root when root, undeleted, and unreachable are passed as flags to --include. From the output below it's apparent it's still being included in the forest, but not at the correct root placement.

Example output from my laptop when running sudo btrview --snapshot --include root unreachable deleted:

Label: None
UUID: fc4e1f06-d5b2-413f-8076-0dc1cd267b3f
Snapshots:
  portables
  machines
  swap
  snapshots
  b6768d17-e97e-41c5-8dbc-3c8779a5ae65
  ├── 2024-02-01T00:08:18.180141-05:00
  ├── 2024-02-05T13:21:49.056598-05:00
  ├── 2024-02-18T15:28:54.408456-05:00 
  ├── 2024-02-18T15:30:48.137286-05:00
  ├── 2024-02-21T20:34:42.104945-05:00
  ├── 2024-02-21T20:36:54.591434-05:00
  ├── 2024-02-23T13:54:49.749831-05:00
  ├── 2024-02-23T15:19:21.933669-05:00
  ├── 2024-02-23T15:20:03.985764-05:00
  ├── 2024-02-23T15:20:06.635266-05:00
  └── 2024-02-23T15:20:13.564159-05:00
  e4884c3c-95c8-d742-ad1f-dd182fa62e80
  └── portables-snap-3
      └── portables-snap-4
  <FS_TREE> on: /

Create a method to retrieve all filesystem paths of subvolumes

Due to the fact btrfs doesn't have just one place where snapshots are stored like ZFS does, they can be anywhere on the filesystem. This causes problems when you want to use them to create a snapshot difftool. What complicates this matter more is that each subvolume can have multiple paths on the filesystem (because mounting a subvolume is just a bind mount, which can be done multiple times), or none at all (if the btrfs root isn't mounted, then all subvolumes aren't necessarily reachable from the filesystem).

As the goal of btrview is to provide a better view of the btrfs filesytem structure and snapshot relationships, I think being able to tell which subvolumes have a path (or multiple paths) on the filesystem, is in the purview of this project. Additionally, if anyone wants to implement a similar feature in their own project then the groundwork will have been laid.

I think the general process for finding the subvolume paths on a particular filesystem is going to look something like this:

  1. Find all subvolume mounts on the filesystem
  2. Find all subvolumes on the filesystem
  3. Find which subvolumes are under which mounts
  4. Resolve the pathnames based on the above information

Steps 1 and 2 are already done via the btrfs class, hopefully 3 and 4 aren't too difficult.

Integrate rich to make cli output pretty

The current default output from treelib isn't bad, but I think it could be more visually appealing.

Things I've thought about incorporating:

  • Dimmed/greyed output for subvolumes that aren't reachable
  • Bold output for subvolumes that are mount points
  • #5
  • Better delineation between different filesystems
  • Limiting long output
  • Maybe emojis or something because that's what the kids like

Right now I think the easiest way to accomplish much of this would be via the rich library. While the rich library does have support for trees, its support is more for visualizing them, not interacting with them, so treelib would still be a dependency. If I had to guess, rich would just act as a layer between the library and the cli, meaning most of it's code would live in btrview.py, or maybe I'll create a separate module for it as btrview.py is getting a bit crowded.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.