Goal

Continue from where I left off last time and implement commands for client chunk and client key management.

Plan

  • Add subcommand obnam client list to list IDs of client chunks.
  • Add subcommand obnam client show to decrypt a client chunk and show its contents.
  • Add subcommand obnam client key generate to generate a new chunk key.
  • Change obnam chnunk subcommands to be able to use keys from the client chunk.

Notes

  • I had left the source tree in a non-working state last time, so I went back to the previous commit. That allows tests to pass.
  • From my notes from last time, I see that I need to change obnam client init prevent creating two clients of the same name. This can't ever be perfect: if different computers run obnam but share a repository, there is no way to prevent them from using the same client name, but in practice this won't be a problem, since they'll have distinct client key. What matters is that for a given client key, we avoid having two clients with the same name. Even more important is that if there are clients with the same name, the user can reliably pick which client chunk to use.
  • Added code, and a scenario, to verify that doesn't happen.
  • Next, obnam client list to list all clients for client key we have.
  • That was easy.
  • Next, obnam client show to show the content of a client chunk. This is an addition to the plan that I only now thought of, but it seems important. It'll also be needed for testing key management.
  • That was straightforward.
  • Next, obnam client key generate to generate a key and add it to the client chunk.
  • This adds a new level of subcommand. I could avoid that by calling it key-generate or even just generate. I initially thought the extra key subcommand would be more logical, but it is more to type for users. I'll do obnam client generate instead.
  • I note, in passing, that the current command line interface is, in general, not particularly nice to use. It's there to have a way to exercise the library part of the crate, not to be convenient to use. If, or when, I start implementing an actual backup program I'll need to design that from scratch from the user point of view. For example, there needs to be configuration file and operations that make sense for making and managing backups, not from the point of view of implementing fundamental building blocks.
  • While implementing generate, I run into the problem that once the client chunk is modified, there are now to chunks for the same client, but the code doesn't realize one is superseded by the other. I will, soon, make generate remove the old chunk, but first I'll change things so that the code base can realize that some chunks are just old versions of the client, and can be ignored.
  • The easy solution is to have a serial number, but updating that when it's possible two obnam processes are updating the chunk repository at the same time is tricky. I don't want to have locking, or to have the repository manage versions.
  • Instead, I'll change the client chunk so that it stores the IDs of all previous client chunks. When we look up the client chunk for a specific client, we ignore all the ones that are referred to by other client chunks. If there are more than one such chunk, we'll treat that as an error. Later, we'll add a way for the user to refer to the client chunk they want to use by chunk ID, but for now, we'll assume there won't be more than one.
  • Doing that is a little bit tricky. It might be worth looking into crates that implement graph algorithms.
  • But I don't need that now, because I'm keeping things very simple.
  • Got obnam client generate done.
  • The remaining thing is to change obnam chunk subcommands to use keys from client chunk by default. Specifically:
    • obnam chunk encrypt --key-name=KEY should use the key named KEY from the client chunk
    • likewise decrypt and inspect
    • the existing --key will continue to work as is
  • Made those changes. It was quite straightforward.
  • Ran mutation tests. Found a missing test. Added the missing test.
  • The code to find the correct version of a client chunk is now duplicated in several places. I will refactor that later. Today I'm already well over time.
  • Merged the branch and pushed.

Summary

I now have a client chunk, and while I expect that this part of the code base will require more work, I got to a good place today. It'll be good to build on this.

Comments?

If you have feedback on this development session, please use the following fediverse thread: https://toot.liw.fi/@liw/114720518998858017.