Kanidm[1]

June 1

My first “official” day of Google Summer of Code! I started by reading @yaleman’s post about logs, which I thought looked like fun to implement. The first thing I did was read his blog post about the subject, and then read another article he linked about using the tracing Rust crate. After I felt like I had a decent understanding, I followed William’s recommendation to look into the daemon/unix files as a starting place for implementing. However, I ran into a few problems right away.

  • I didn’t know if I needed to set up my own Kanidm instance for testing.
  • How was I supposed to actually test any changes that I made?

I saw there was some logging activity around kanidm_unix_int/src/daemon.rs, so I ended up familiarizing myself with the content of that file by doing some general idiomatic Rust refactoring since I didn’t know how to actually test any changes I wanted to implement. I responded to the thread on @yaleman’s post and asked clarifying questions, got some feedback, and responded again with a few more questions. I ended the day here, but excited to attempt an initial implementation of tracing the next day!

June 2

Day two began by diving into my implementation of the tracing crate. I followed William’s advice by running the unit tests only in kanidm_unix_int and found the tests that produced logs, and started by finding where in code they yielded the logs. I added tracing to the dependencies, set up a little span to capture the context, and exchanged the error! macro call with an event! macro call that tracing uses. I ran the test with --nocapture but I didn’t get anything where there used to be a log output, so I went back to the docs and found that I need to use a subscriber for the tracing to capture logs and send them to stdout/stderr. It said that subscribers were used for applications, and that some other strategy is used for libraries, so I ran with the assumption that Kanidm was an application for now.

After some more fiddling around, I got basic logging working with tracing, now we have pretty colors! I then wanted to explore other types of subscribers like @yaleman suggested with the JSON logging.

I spent some more time digging through documentation to get basic JSON formatting working, but still didn’t understand how to configure between the human-readable format and JSON. I was also confused about how to avoid setting a global default subscriber, and instead use a subscriber that only applied to a certain scope.

At the end of the day, I wasn’t able to figure it out because of an issue with having await calls inside of a closure, and I wasn’t able to make the closure async because I had no way of blocking on it to actually run. I spent some time also reading the Rust Async Book, but wasn’t able to make further progress. I ended the day be sending a long email to William describing my issues. I was proud of myself for putting in significant effort before reaching for help, and I think it reflects the point in my week 0 post about being a more independent thinker.

June 3

Started the day by reviewing @Firstyear’s PR “Add email syntax #465”. I realized I would be spending a lot of time on the GibHub web UI, so I considered downloading GitHub desktop but decided against it (because lazy). I spent two hours reviewing it, and was able to ask a lot of questions and even provide some pointers for how to clean up the code! One suggestion I was particularly proud of was identifying an area that could be cleaned up a lot by using the built-in all function for iterators, which even provides the benefit of short-circuiting in this case.

Original:

SyntaxType::EmailAddress => ava.iter().fold(Ok(()), |acc, v| {
    acc.and_then(|_| {
        if v.is_email_address() {
            Ok(())
        } else {
            Err(SchemaError::InvalidAttributeSyntax(a.to_string()))
        }
    })
}),

My suggestion:

SyntaxType::EmailAddress => ava.iter()
    .all(Value::is_email_address)
    .then(|| ())
    .ok_or_else(|| SchemaError::InvalidAttributeSyntax(a.to_string())),

I had so much fun doing the code review that I was telling my friends how cool I thought it was at lunch!

After I submitted feedback, I shifted gears to review wisdom William had to bestow upon me from the email I sent last night. For determining how to switch between human-readable logging and JSON logging, he suggested I look through the unix_config.rs file. However, I wasn’t sure how to use it, as the config objects are never passed around. Also, I wasn’t sure if it I had to add a new custom field, or if there was an existing one.

Since I wasn’t sure what to do, I ended the day by taking William’s other advice, which was to make a draft PR outlining my issues so I could get specific feedback on how to resolve the scoped subscribers issue I was having.

June 4

Had a light day because of other things I had to deal with. I mostly spent time figuring out how my weekly blog posts would work, and spent two hours writing and revising them. I’m hoping to do a better job at journaling in the future so I can spend less time editing them, because it’s definitely not as exciting as coding.

In addition to getting the blog set up, I also added some clarifying details on my PR I sent the previous day.

Weekly Reflections

Looking back on this week, I’m not sure if I want to really count it as my first week since I started early, because I’ve been taking a lot of time warming up to the project and figuring out how to balance my time spent on it with other things. However, I do feel like I’m learning a lot, and I think I’ll be ready to dive deeper into the project next week.

I’m also making good progress towards the goals I set for myself! Doing the code review provided really solid experience reading through other peoples’ code, and I felt like I was able to ask meaningful question and give relevant suggestions. I also learned how to actually make comments through the GitHub UI, something I’ve never had to do before.


I might poke around some more over the weekend, but if not, I’m super excited to dive deeper next week!

Written on June 4, 2021