From 82e7ac75954c973a5c59a02684788c0fb26e14dd Mon Sep 17 00:00:00 2001 From: Martin Ashby Date: Sat, 21 Dec 2024 22:18:18 +0000 Subject: Bump zine 0.3.0 -> 0.8.0 Fix a lot of associated breakage Fix broken rss.xml file as highlighted to me by Matthijs van der Wild (thanks!) --- content/about/cv.md | 42 ----------- content/about/cv.smd | 42 +++++++++++ content/about/index.md | 10 --- content/about/index.smd | 10 +++ content/index.md | 6 -- content/index.smd | 6 ++ content/posts/2018-05-31-new-site.md | 15 ---- content/posts/2018-05-31-new-site.smd | 15 ++++ content/posts/2018-06-01-mailu.md | 54 -------------- content/posts/2018-06-01-mailu.smd | 54 ++++++++++++++ content/posts/2018-06-02-unicornpaint.md | 13 ---- content/posts/2018-06-02-unicornpaint.smd | 13 ++++ content/posts/2021-09-17-restart.md | 20 ------ content/posts/2021-09-17-restart.smd | 20 ++++++ content/posts/2021-09-18-maddy.md | 13 ---- content/posts/2021-09-18-maddy.smd | 13 ++++ content/posts/2021-09-19-longboard-setup.md | 23 ------ content/posts/2021-09-19-longboard-setup.smd | 23 ++++++ content/posts/2021-09-21-manjaro.md | 16 ----- content/posts/2021-09-21-manjaro.smd | 16 +++++ content/posts/2021-09-26-pine64.md | 15 ---- content/posts/2021-09-26-pine64.smd | 15 ++++ content/posts/2021-09-29-bike.md | 17 ----- content/posts/2021-09-29-bike.smd | 17 +++++ content/posts/2021-09-29-recipe.md | 14 ---- content/posts/2021-09-29-recipe.smd | 14 ++++ content/posts/2021-10-01-blog.md | 14 ---- content/posts/2021-10-01-blog.smd | 14 ++++ content/posts/2021-10-06-clojure.md | 14 ---- content/posts/2021-10-06-clojure.smd | 14 ++++ content/posts/2021-10-30-openbsd.md | 84 ---------------------- content/posts/2021-10-30-openbsd.smd | 84 ++++++++++++++++++++++ content/posts/2021-11-05-postgres-query-rewrite.md | 19 ----- .../posts/2021-11-05-postgres-query-rewrite.smd | 19 +++++ content/posts/2021-11-09-longboard-2.md | 16 ----- content/posts/2021-11-09-longboard-2.smd | 17 +++++ content/posts/2021-11-14-backups.md | 17 ----- content/posts/2021-11-14-backups.smd | 17 +++++ content/posts/2021-12-04-contacts.md | 14 ---- content/posts/2021-12-04-contacts.smd | 14 ++++ content/posts/2021-12-28-chat-server-protocol.md | 33 --------- content/posts/2021-12-28-chat-server-protocol.smd | 33 +++++++++ .../posts/2022-02-11-philosophy-software-dev.md | 28 -------- .../posts/2022-02-11-philosophy-software-dev.smd | 28 ++++++++ content/posts/2022-02-23-wordle.md | 18 ----- content/posts/2022-02-23-wordle.smd | 18 +++++ content/posts/2022-03-19-wildcard.md | 12 ---- content/posts/2022-03-19-wildcard.smd | 12 ++++ content/posts/2022-03-27-fossil.md | 11 --- content/posts/2022-03-27-fossil.smd | 11 +++ content/posts/2022-04-30-longboard-3.md | 23 ------ content/posts/2022-04-30-longboard-3.smd | 23 ++++++ content/posts/2022-05-07-stolen-focus.md | 21 ------ content/posts/2022-05-07-stolen-focus.smd | 21 ++++++ content/posts/2022-06-09-rustlings.md | 14 ---- content/posts/2022-06-09-rustlings.smd | 14 ++++ content/posts/2022-07-09-longboard-4.md | 14 ---- content/posts/2022-07-09-longboard-4.smd | 14 ++++ content/posts/2022-07-30-fossil2.md | 11 --- content/posts/2022-07-30-fossil2.smd | 11 +++ content/posts/2022-09-09-serverless.md | 21 ------ content/posts/2022-09-09-serverless.smd | 21 ++++++ content/posts/2022-09-25-back-to-git.md | 13 ---- content/posts/2022-09-25-back-to-git.smd | 13 ++++ content/posts/2022-10-07-blocky.md | 13 ---- content/posts/2022-10-07-blocky.smd | 13 ++++ content/posts/2022-10-09-quine.md | 12 ---- content/posts/2022-10-09-quine.smd | 12 ++++ content/posts/2022-10-09-skateboard-1.md | 19 ----- content/posts/2022-10-09-skateboard-1.smd | 21 ++++++ content/posts/2022-10-14-blogsite.md | 12 ---- content/posts/2022-10-14-blogsite.smd | 12 ++++ content/posts/2022-10-14-caddy.md | 13 ---- content/posts/2022-10-14-caddy.smd | 13 ++++ content/posts/2022-10-15-blogsite2.md | 11 --- content/posts/2022-10-15-blogsite2.smd | 11 +++ content/posts/2022-12-04-aoc.md | 11 --- content/posts/2022-12-04-aoc.smd | 11 +++ content/posts/2022-12-20-longboard-5.md | 15 ---- content/posts/2022-12-20-longboard-5.smd | 17 +++++ content/posts/2022-12-26-spotifyd.md | 23 ------ content/posts/2022-12-26-spotifyd.smd | 23 ++++++ content/posts/2022-12-30-comments.md | 17 ----- content/posts/2022-12-30-comments.smd | 17 +++++ content/posts/2022-12-31-cgit.md | 25 ------- content/posts/2022-12-31-cgit.smd | 25 +++++++ content/posts/2023-01-31-oso.md | 64 ----------------- content/posts/2023-01-31-oso.smd | 64 +++++++++++++++++ ...2023-02-05-book-site-reliability-engineering.md | 19 ----- ...023-02-05-book-site-reliability-engineering.smd | 19 +++++ content/posts/2023-02-05-semantic-dissonance.md | 11 --- content/posts/2023-02-05-semantic-dissonance.smd | 11 +++ ...-04-09-designing-data-intensive-applications.md | 15 ---- ...04-09-designing-data-intensive-applications.smd | 15 ++++ content/posts/2023-06-16-bike.md | 16 ----- content/posts/2023-06-16-bike.smd | 16 +++++ content/posts/2023-08-11-4-eyes.md | 17 ----- content/posts/2023-08-11-4-eyes.smd | 17 +++++ content/posts/2023-08-22-comments-2.md | 17 ----- content/posts/2023-08-22-comments-2.smd | 17 +++++ content/posts/2023-09-12-mcl.md | 19 ----- content/posts/2023-09-12-mcl.smd | 19 +++++ content/posts/2023-10-01-parable-of-the-sower.md | 15 ---- content/posts/2023-10-01-parable-of-the-sower.smd | 15 ++++ content/posts/2023-10-07-zipdl.md | 11 --- content/posts/2023-10-07-zipdl.smd | 11 +++ content/posts/2023-11-25-roc.md | 13 ---- content/posts/2023-11-25-roc.smd | 13 ++++ content/posts/2023-11-26-skateboard-2.md | 15 ---- content/posts/2023-11-26-skateboard-2.smd | 17 +++++ content/posts/2023-12-01-aoc2023.md | 12 ---- content/posts/2023-12-01-aoc2023.smd | 12 ++++ content/posts/2024-01-26-data-oriented-design.md | 17 ----- content/posts/2024-01-26-data-oriented-design.smd | 17 +++++ content/posts/2024-01-26-dyn.md | 13 ---- content/posts/2024-01-26-dyn.smd | 13 ++++ content/posts/2024-02-01-1brc.md | 11 --- content/posts/2024-02-01-1brc.smd | 11 +++ content/posts/2024-02-05-phones.md | 13 ---- content/posts/2024-02-05-phones.smd | 13 ++++ content/posts/2024-03-01-communication.md | 46 ------------ content/posts/2024-03-01-communication.smd | 46 ++++++++++++ content/posts/2024-03-03-catb.md | 16 ----- content/posts/2024-03-03-catb.smd | 16 +++++ content/posts/2024-03-27-zine.md | 16 ----- content/posts/2024-03-27-zine.smd | 16 +++++ content/posts/2024-03-31-stranger-times.md | 12 ---- content/posts/2024-03-31-stranger-times.smd | 12 ++++ content/posts/2024-05-23-zigvm.md | 13 ---- content/posts/2024-05-23-zigvm.smd | 13 ++++ content/posts/2024-08-09-bike.md | 29 -------- content/posts/2024-08-09-bike.smd | 29 ++++++++ content/posts/2024-08-23-book-meltdown.md | 14 ---- content/posts/2024-08-23-book-meltdown.smd | 14 ++++ content/posts/2024-08-24-wyag.md | 14 ---- content/posts/2024-08-24-wyag.smd | 14 ++++ content/posts/2024-12-01-aoc2024.md | 13 ---- content/posts/2024-12-01-aoc2024.smd | 13 ++++ content/posts/index.md | 10 --- content/posts/index.smd | 12 ++++ content/projects/index.md | 6 -- content/projects/index.smd | 6 ++ content/projects/zigvm.md | 31 -------- content/projects/zigvm.smd | 31 ++++++++ content/projects/zipdl.md | 31 -------- content/projects/zipdl.smd | 31 ++++++++ 146 files changed, 1384 insertions(+), 1375 deletions(-) delete mode 100644 content/about/cv.md create mode 100644 content/about/cv.smd delete mode 100644 content/about/index.md create mode 100644 content/about/index.smd delete mode 100644 content/index.md create mode 100644 content/index.smd delete mode 100644 content/posts/2018-05-31-new-site.md create mode 100644 content/posts/2018-05-31-new-site.smd delete mode 100644 content/posts/2018-06-01-mailu.md create mode 100644 content/posts/2018-06-01-mailu.smd delete mode 100644 content/posts/2018-06-02-unicornpaint.md create mode 100644 content/posts/2018-06-02-unicornpaint.smd delete mode 100644 content/posts/2021-09-17-restart.md create mode 100644 content/posts/2021-09-17-restart.smd delete mode 100644 content/posts/2021-09-18-maddy.md create mode 100644 content/posts/2021-09-18-maddy.smd delete mode 100644 content/posts/2021-09-19-longboard-setup.md create mode 100644 content/posts/2021-09-19-longboard-setup.smd delete mode 100644 content/posts/2021-09-21-manjaro.md create mode 100644 content/posts/2021-09-21-manjaro.smd delete mode 100644 content/posts/2021-09-26-pine64.md create mode 100644 content/posts/2021-09-26-pine64.smd delete mode 100644 content/posts/2021-09-29-bike.md create mode 100644 content/posts/2021-09-29-bike.smd delete mode 100644 content/posts/2021-09-29-recipe.md create mode 100644 content/posts/2021-09-29-recipe.smd delete mode 100644 content/posts/2021-10-01-blog.md create mode 100644 content/posts/2021-10-01-blog.smd delete mode 100644 content/posts/2021-10-06-clojure.md create mode 100644 content/posts/2021-10-06-clojure.smd delete mode 100644 content/posts/2021-10-30-openbsd.md create mode 100644 content/posts/2021-10-30-openbsd.smd delete mode 100644 content/posts/2021-11-05-postgres-query-rewrite.md create mode 100644 content/posts/2021-11-05-postgres-query-rewrite.smd delete mode 100644 content/posts/2021-11-09-longboard-2.md create mode 100644 content/posts/2021-11-09-longboard-2.smd delete mode 100644 content/posts/2021-11-14-backups.md create mode 100644 content/posts/2021-11-14-backups.smd delete mode 100644 content/posts/2021-12-04-contacts.md create mode 100644 content/posts/2021-12-04-contacts.smd delete mode 100644 content/posts/2021-12-28-chat-server-protocol.md create mode 100644 content/posts/2021-12-28-chat-server-protocol.smd delete mode 100644 content/posts/2022-02-11-philosophy-software-dev.md create mode 100644 content/posts/2022-02-11-philosophy-software-dev.smd delete mode 100644 content/posts/2022-02-23-wordle.md create mode 100644 content/posts/2022-02-23-wordle.smd delete mode 100644 content/posts/2022-03-19-wildcard.md create mode 100644 content/posts/2022-03-19-wildcard.smd delete mode 100644 content/posts/2022-03-27-fossil.md create mode 100644 content/posts/2022-03-27-fossil.smd delete mode 100644 content/posts/2022-04-30-longboard-3.md create mode 100644 content/posts/2022-04-30-longboard-3.smd delete mode 100644 content/posts/2022-05-07-stolen-focus.md create mode 100644 content/posts/2022-05-07-stolen-focus.smd delete mode 100644 content/posts/2022-06-09-rustlings.md create mode 100644 content/posts/2022-06-09-rustlings.smd delete mode 100644 content/posts/2022-07-09-longboard-4.md create mode 100644 content/posts/2022-07-09-longboard-4.smd delete mode 100644 content/posts/2022-07-30-fossil2.md create mode 100644 content/posts/2022-07-30-fossil2.smd delete mode 100644 content/posts/2022-09-09-serverless.md create mode 100644 content/posts/2022-09-09-serverless.smd delete mode 100644 content/posts/2022-09-25-back-to-git.md create mode 100644 content/posts/2022-09-25-back-to-git.smd delete mode 100644 content/posts/2022-10-07-blocky.md create mode 100644 content/posts/2022-10-07-blocky.smd delete mode 100644 content/posts/2022-10-09-quine.md create mode 100644 content/posts/2022-10-09-quine.smd delete mode 100644 content/posts/2022-10-09-skateboard-1.md create mode 100644 content/posts/2022-10-09-skateboard-1.smd delete mode 100644 content/posts/2022-10-14-blogsite.md create mode 100644 content/posts/2022-10-14-blogsite.smd delete mode 100644 content/posts/2022-10-14-caddy.md create mode 100644 content/posts/2022-10-14-caddy.smd delete mode 100644 content/posts/2022-10-15-blogsite2.md create mode 100644 content/posts/2022-10-15-blogsite2.smd delete mode 100644 content/posts/2022-12-04-aoc.md create mode 100644 content/posts/2022-12-04-aoc.smd delete mode 100644 content/posts/2022-12-20-longboard-5.md create mode 100644 content/posts/2022-12-20-longboard-5.smd delete mode 100644 content/posts/2022-12-26-spotifyd.md create mode 100644 content/posts/2022-12-26-spotifyd.smd delete mode 100644 content/posts/2022-12-30-comments.md create mode 100644 content/posts/2022-12-30-comments.smd delete mode 100644 content/posts/2022-12-31-cgit.md create mode 100644 content/posts/2022-12-31-cgit.smd delete mode 100644 content/posts/2023-01-31-oso.md create mode 100644 content/posts/2023-01-31-oso.smd delete mode 100644 content/posts/2023-02-05-book-site-reliability-engineering.md create mode 100644 content/posts/2023-02-05-book-site-reliability-engineering.smd delete mode 100644 content/posts/2023-02-05-semantic-dissonance.md create mode 100644 content/posts/2023-02-05-semantic-dissonance.smd delete mode 100644 content/posts/2023-04-09-designing-data-intensive-applications.md create mode 100644 content/posts/2023-04-09-designing-data-intensive-applications.smd delete mode 100644 content/posts/2023-06-16-bike.md create mode 100644 content/posts/2023-06-16-bike.smd delete mode 100644 content/posts/2023-08-11-4-eyes.md create mode 100644 content/posts/2023-08-11-4-eyes.smd delete mode 100644 content/posts/2023-08-22-comments-2.md create mode 100644 content/posts/2023-08-22-comments-2.smd delete mode 100644 content/posts/2023-09-12-mcl.md create mode 100644 content/posts/2023-09-12-mcl.smd delete mode 100644 content/posts/2023-10-01-parable-of-the-sower.md create mode 100644 content/posts/2023-10-01-parable-of-the-sower.smd delete mode 100644 content/posts/2023-10-07-zipdl.md create mode 100644 content/posts/2023-10-07-zipdl.smd delete mode 100644 content/posts/2023-11-25-roc.md create mode 100644 content/posts/2023-11-25-roc.smd delete mode 100644 content/posts/2023-11-26-skateboard-2.md create mode 100644 content/posts/2023-11-26-skateboard-2.smd delete mode 100644 content/posts/2023-12-01-aoc2023.md create mode 100644 content/posts/2023-12-01-aoc2023.smd delete mode 100644 content/posts/2024-01-26-data-oriented-design.md create mode 100644 content/posts/2024-01-26-data-oriented-design.smd delete mode 100644 content/posts/2024-01-26-dyn.md create mode 100644 content/posts/2024-01-26-dyn.smd delete mode 100644 content/posts/2024-02-01-1brc.md create mode 100644 content/posts/2024-02-01-1brc.smd delete mode 100644 content/posts/2024-02-05-phones.md create mode 100644 content/posts/2024-02-05-phones.smd delete mode 100644 content/posts/2024-03-01-communication.md create mode 100644 content/posts/2024-03-01-communication.smd delete mode 100644 content/posts/2024-03-03-catb.md create mode 100644 content/posts/2024-03-03-catb.smd delete mode 100644 content/posts/2024-03-27-zine.md create mode 100644 content/posts/2024-03-27-zine.smd delete mode 100644 content/posts/2024-03-31-stranger-times.md create mode 100644 content/posts/2024-03-31-stranger-times.smd delete mode 100644 content/posts/2024-05-23-zigvm.md create mode 100644 content/posts/2024-05-23-zigvm.smd delete mode 100644 content/posts/2024-08-09-bike.md create mode 100644 content/posts/2024-08-09-bike.smd delete mode 100644 content/posts/2024-08-23-book-meltdown.md create mode 100644 content/posts/2024-08-23-book-meltdown.smd delete mode 100644 content/posts/2024-08-24-wyag.md create mode 100644 content/posts/2024-08-24-wyag.smd delete mode 100644 content/posts/2024-12-01-aoc2024.md create mode 100644 content/posts/2024-12-01-aoc2024.smd delete mode 100644 content/posts/index.md create mode 100644 content/posts/index.smd delete mode 100644 content/projects/index.md create mode 100644 content/projects/index.smd delete mode 100644 content/projects/zigvm.md create mode 100644 content/projects/zigvm.smd delete mode 100644 content/projects/zipdl.md create mode 100644 content/projects/zipdl.smd (limited to 'content') diff --git a/content/about/cv.md b/content/about/cv.md deleted file mode 100644 index 93081ca..0000000 --- a/content/about/cv.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -.title = "CV", -.author = "Martin Ashby", -.date = @date("2024-04-19T20:38:00Z"), -.layout = "single.shtml", ---- - -# Martin Ashby - Software Engineer - -I solve problems in software. My two strongest skills are technical design & architecture, and debugging. - -## Education / Employment History - -- 2018 - Present Patients Know Best, Software engineer -- 2010 - 2018 The Phoenix Partnership, Software Engineer -- 2007 - 2010 University of Warwick, Physics BSc (1st class) - -## Projects - -In 2023/2024 I am transitioning PKBs primary web application from WildFly to Spring Boot. This is an important step for improving our security, and for reducing onboarding effort both for new developers and mental overhead for the existing development team. This requires deep knowledge of all the libraries and technologies used in the existing application and their analogs in Spring Boot. It also requires a lot of debugging! - -In 2022/2023 I helped to define a new software architecture for PKB. The new architecture had to overcome several pain points of the existing system, and also enable new possibilities. I designed this system in conjunction with the CTO, product management team, and my peers. The new architecture better allowed PKB to focus on their core competencies while outsourcing essential but non-core items such as authentication, audit and orchestration to managed or self-hosted third party software. This required collaboration with many groups including co-developers, product management teams, and third parties. - -From 2021 I have led the 'application & infrastructure engineering' team at PKB. Our team is responsible for implementing cross-cutting system changes to improve the security and scalability of PKB. This requires good domain knowledge and situational awareness in order to choose the right projects to ensure PKB's future operational needs are met. It also requires the soft skills necessary to take care of a small team (2-4 engineers, senior and junior) - -From 2021 I have been chair of PKB's 'architecture clinic', a weekly forum for discussing PKB architecture and design. This requires both the technical chops to understand the problems that the engineering team face, as well as the soft skills to ensure that decisions are made and that engineers are on-board with them. - -In 2020 I moved PKB from running on co-located hosting using docker-swarm at a small provider, to Google Cloud Platform using kubernetes. This allowed PKB to significantly improve their operational security, as well as enabled accelerated development by using google managed services. This required learning about kubernetes, google cloud platform, networking in a cloud environment, and a host of other technical details. This also required planning and managing the final switchover in conjunction with my co-developers and our support team. - -In 2016-2017 I worked on TPP's mobile applications and their backend; expanding their existing backend to support new patient-facing mobile applications. I also worked on the client side of the initial version of TPP's [Airmid UK](https://play.google.com/store/apps/details?id=px.mw.android.aihealth.patient.live.production&pcampaignid=web_share) app. - -I am comfortable using a variety of programming languages, and I have used a variety of frameworks. My current work uses Java and Spring. I'm very open to learning new technology as it becomes necessary or interesting. My current favourite language is Zig. Ask me why! - -## Links - -- [Blog](https://mfashby.net) -- [GitHub](https://github.com/MFAshby) -- [Code](https://code.mfashby.net/) - -## Contact - -[martin@mfashby.net](mailto:martin@mfashby.net) \ No newline at end of file diff --git a/content/about/cv.smd b/content/about/cv.smd new file mode 100644 index 0000000..93081ca --- /dev/null +++ b/content/about/cv.smd @@ -0,0 +1,42 @@ +--- +.title = "CV", +.author = "Martin Ashby", +.date = @date("2024-04-19T20:38:00Z"), +.layout = "single.shtml", +--- + +# Martin Ashby - Software Engineer + +I solve problems in software. My two strongest skills are technical design & architecture, and debugging. + +## Education / Employment History + +- 2018 - Present Patients Know Best, Software engineer +- 2010 - 2018 The Phoenix Partnership, Software Engineer +- 2007 - 2010 University of Warwick, Physics BSc (1st class) + +## Projects + +In 2023/2024 I am transitioning PKBs primary web application from WildFly to Spring Boot. This is an important step for improving our security, and for reducing onboarding effort both for new developers and mental overhead for the existing development team. This requires deep knowledge of all the libraries and technologies used in the existing application and their analogs in Spring Boot. It also requires a lot of debugging! + +In 2022/2023 I helped to define a new software architecture for PKB. The new architecture had to overcome several pain points of the existing system, and also enable new possibilities. I designed this system in conjunction with the CTO, product management team, and my peers. The new architecture better allowed PKB to focus on their core competencies while outsourcing essential but non-core items such as authentication, audit and orchestration to managed or self-hosted third party software. This required collaboration with many groups including co-developers, product management teams, and third parties. + +From 2021 I have led the 'application & infrastructure engineering' team at PKB. Our team is responsible for implementing cross-cutting system changes to improve the security and scalability of PKB. This requires good domain knowledge and situational awareness in order to choose the right projects to ensure PKB's future operational needs are met. It also requires the soft skills necessary to take care of a small team (2-4 engineers, senior and junior) + +From 2021 I have been chair of PKB's 'architecture clinic', a weekly forum for discussing PKB architecture and design. This requires both the technical chops to understand the problems that the engineering team face, as well as the soft skills to ensure that decisions are made and that engineers are on-board with them. + +In 2020 I moved PKB from running on co-located hosting using docker-swarm at a small provider, to Google Cloud Platform using kubernetes. This allowed PKB to significantly improve their operational security, as well as enabled accelerated development by using google managed services. This required learning about kubernetes, google cloud platform, networking in a cloud environment, and a host of other technical details. This also required planning and managing the final switchover in conjunction with my co-developers and our support team. + +In 2016-2017 I worked on TPP's mobile applications and their backend; expanding their existing backend to support new patient-facing mobile applications. I also worked on the client side of the initial version of TPP's [Airmid UK](https://play.google.com/store/apps/details?id=px.mw.android.aihealth.patient.live.production&pcampaignid=web_share) app. + +I am comfortable using a variety of programming languages, and I have used a variety of frameworks. My current work uses Java and Spring. I'm very open to learning new technology as it becomes necessary or interesting. My current favourite language is Zig. Ask me why! + +## Links + +- [Blog](https://mfashby.net) +- [GitHub](https://github.com/MFAshby) +- [Code](https://code.mfashby.net/) + +## Contact + +[martin@mfashby.net](mailto:martin@mfashby.net) \ No newline at end of file diff --git a/content/about/index.md b/content/about/index.md deleted file mode 100644 index b6f642c..0000000 --- a/content/about/index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -.title = "About", -.author = "Martin Ashby", -.date = @date("2024-03-01T23:59:52Z"), -.layout = "list.shtml", ---- - -Hi, my name's Martin. - -I write about software engineering and other stuff. \ No newline at end of file diff --git a/content/about/index.smd b/content/about/index.smd new file mode 100644 index 0000000..b6f642c --- /dev/null +++ b/content/about/index.smd @@ -0,0 +1,10 @@ +--- +.title = "About", +.author = "Martin Ashby", +.date = @date("2024-03-01T23:59:52Z"), +.layout = "list.shtml", +--- + +Hi, my name's Martin. + +I write about software engineering and other stuff. \ No newline at end of file diff --git a/content/index.md b/content/index.md deleted file mode 100644 index a6af1fc..0000000 --- a/content/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -.title = "Home", -.author = "Martin Ashby", -.date = @date("2024-03-27T20:26:45+00:00"), -.layout = "redirect.shtml", ---- \ No newline at end of file diff --git a/content/index.smd b/content/index.smd new file mode 100644 index 0000000..a6af1fc --- /dev/null +++ b/content/index.smd @@ -0,0 +1,6 @@ +--- +.title = "Home", +.author = "Martin Ashby", +.date = @date("2024-03-27T20:26:45+00:00"), +.layout = "redirect.shtml", +--- \ No newline at end of file diff --git a/content/posts/2018-05-31-new-site.md b/content/posts/2018-05-31-new-site.md deleted file mode 100644 index 8e8a1e1..0000000 --- a/content/posts/2018-05-31-new-site.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -.title = "New Site", -.author = "Martin Ashby", -.date = @date("2018-05-31T17:51:07+0100"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I'm intending to write more online about the stuff I tinker with. - -You can expect posts about -* what I do with my [Raspberry Pi](https://www.raspberrypi.org), -* websites and servers that I run including [my wife's blog](https://heyworlditshenry.com) and my [email server](https://mail.mfashby.net) -* more physical projects like getting a [RepRap](https://reprap.org/) up and running - diff --git a/content/posts/2018-05-31-new-site.smd b/content/posts/2018-05-31-new-site.smd new file mode 100644 index 0000000..8e8a1e1 --- /dev/null +++ b/content/posts/2018-05-31-new-site.smd @@ -0,0 +1,15 @@ +--- +.title = "New Site", +.author = "Martin Ashby", +.date = @date("2018-05-31T17:51:07+0100"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I'm intending to write more online about the stuff I tinker with. + +You can expect posts about +* what I do with my [Raspberry Pi](https://www.raspberrypi.org), +* websites and servers that I run including [my wife's blog](https://heyworlditshenry.com) and my [email server](https://mail.mfashby.net) +* more physical projects like getting a [RepRap](https://reprap.org/) up and running + diff --git a/content/posts/2018-06-01-mailu.md b/content/posts/2018-06-01-mailu.md deleted file mode 100644 index 6eb75dd..0000000 --- a/content/posts/2018-06-01-mailu.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -.title = "Mailu", -.author = "Martin Ashby", -.date = @date("2018-06-01T20:17:00+0100"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -## My search for an email server - -![Rainloop Screenshot](mailu_screenshot.png) - -A big theme in the news recently is data protection, how your personal data is being used (and abused), and taking back control of your data. Part of the problem is that people's personal data is kept in huge private corporate networks, and historically companies have been able to do (essentially) whatever they like with it. I started investigating how difficult it would be to really re-take control of my personal data - beginning with my email. - -Email is complicated: this is because it is old, and it has changed over time. [One of the first articles I found](https://www.digitalocean.com/community/tutorials/why-you-may-not-want-to-run-your-own-mail-serve) is a quick rundown of how complex the email system is. [Ars technica][ars-technica-guide] ran a guide for setting up your own email server: - ->Why do battle with arcane dragons to roll your own e-mail solution? - -The arcane dragons are the pieces of software that have become the most popular choices for email servers. A typical email server configuration contains the following pieces of open-source software: dovecot, postfix, spamassassin, clamav, sendmail, roundcube, mysql. Each of them fills a different role in the email system, and each of them can be configured to operate in many different ways. - -I began setting up my email server in this way, however I gave up pretty quickly: I found that walkthroughs on the internet were often out of date, and configuration options had changed or been removed. I also found it really difficult to understand from the guides how all the pieces of the puzzle fit together. I started looking for alternative routes. - -Microsoft Exchange Server fulfils all the roles of the separate open-source components in a single piece of software. This sounds much easier to configure: however I don't have a Windows server, and nor do I want to pay licensing costs for it. - -I started looking for an open-source project that fulfils the same role. I found [Maddy](https://github.com/emersion/maddy), inspired by the new minimal-configuration http/2 server [Caddy][caddy]. Sadly, the project is seriously incomplete right now, but the principle sounds great: a self-contained email server with minimal configuration conforming to best practices by default. - -Although I made a [little effort](https://github.com/MFAshby/gomail) to cobble together this project into a working email server, I discovered this was a much bigger task than I had anticipated. I discovered some more arcane dragons in the form of the email standards for SMTP and IMAP. These are old, stateful protocols with many extensions, versions and awkward syntax. Modern systems are built with REST APIs for a reason: they are much quicker for the developer to understand and build with (they are also way easier to load balance, due to the lack of state) - -I came back around to the idea of using the existing software, but this time I started looking for pre-configured systems. I discovered [iRedMail][iredmail] which claims to turn a fresh Debian or Ubuntu install into a working email server. This isn't bad, but I want to run a few other services from my Raspberry as well, and I'd rather not clobber them by re-installing Debian. - -This approach actually leads really neatly onto the last solution I tried, and the one I actually have working: [Mailu][mailu]. This project provides all the same open-source email components (postfix, dovecot), but pre-configured and packaged as [Docker][docker] images. I feel like this is the best approach for a few reasons: - -* You don't need a fresh Debian install, you just need a working Docker host. -* The hard configuration has been done for you. Just a single config file with a few easy to understand options is required. -* It's portable: copy over the mailu directory and the docker-compose.yml file to another machine, execute `docker-compose up -d` and it's back online with all the same accounts. -* An admin interface is included. -* It's open source so you can check if it conforms to current security practices, and modify it if you need to. -* The maintainer [kaiyou](https://github.com/kaiyou) is very helpful, and gratefully accepts pull requests. - -Although the project didn't work out of the box with Raspberry Pi this was a pretty easy thing to fix. I now maintain a permanent fork of mailu for Raspberry Pi over [here][mailu-rpi] - -[rpi]:https://www.raspberrypi.org/ -[dovecot-basic]:https://wiki.dovecot.org/BasicConfiguration -[ars-technica-guide]:https://arstechnica.com/information-technology/2014/02/how-to-run-your-own-e-mail-server-with-your-own-domain-part-1/ -[golang]:https://golang.org/ -[caddy]:https://caddyserver.com/ -[gomail]:https://github.com/MFAshby/gomail -[emersion]:https://github.com/emersion -[maddy]:https://github.com/emersion/maddy -[caddy-forum-non-http]:https://caddy.community/t/server-types-other-than-http/65/7 -[iredmail]:https://www.iredmail.org/ -[mailu]:https://github.com/Mailu/Mailu -[docker]:http://docker.io/ -[mailu-rpi]:https://github.com/MFAshby/mailu diff --git a/content/posts/2018-06-01-mailu.smd b/content/posts/2018-06-01-mailu.smd new file mode 100644 index 0000000..6eb75dd --- /dev/null +++ b/content/posts/2018-06-01-mailu.smd @@ -0,0 +1,54 @@ +--- +.title = "Mailu", +.author = "Martin Ashby", +.date = @date("2018-06-01T20:17:00+0100"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +## My search for an email server + +![Rainloop Screenshot](mailu_screenshot.png) + +A big theme in the news recently is data protection, how your personal data is being used (and abused), and taking back control of your data. Part of the problem is that people's personal data is kept in huge private corporate networks, and historically companies have been able to do (essentially) whatever they like with it. I started investigating how difficult it would be to really re-take control of my personal data - beginning with my email. + +Email is complicated: this is because it is old, and it has changed over time. [One of the first articles I found](https://www.digitalocean.com/community/tutorials/why-you-may-not-want-to-run-your-own-mail-serve) is a quick rundown of how complex the email system is. [Ars technica][ars-technica-guide] ran a guide for setting up your own email server: + +>Why do battle with arcane dragons to roll your own e-mail solution? + +The arcane dragons are the pieces of software that have become the most popular choices for email servers. A typical email server configuration contains the following pieces of open-source software: dovecot, postfix, spamassassin, clamav, sendmail, roundcube, mysql. Each of them fills a different role in the email system, and each of them can be configured to operate in many different ways. + +I began setting up my email server in this way, however I gave up pretty quickly: I found that walkthroughs on the internet were often out of date, and configuration options had changed or been removed. I also found it really difficult to understand from the guides how all the pieces of the puzzle fit together. I started looking for alternative routes. + +Microsoft Exchange Server fulfils all the roles of the separate open-source components in a single piece of software. This sounds much easier to configure: however I don't have a Windows server, and nor do I want to pay licensing costs for it. + +I started looking for an open-source project that fulfils the same role. I found [Maddy](https://github.com/emersion/maddy), inspired by the new minimal-configuration http/2 server [Caddy][caddy]. Sadly, the project is seriously incomplete right now, but the principle sounds great: a self-contained email server with minimal configuration conforming to best practices by default. + +Although I made a [little effort](https://github.com/MFAshby/gomail) to cobble together this project into a working email server, I discovered this was a much bigger task than I had anticipated. I discovered some more arcane dragons in the form of the email standards for SMTP and IMAP. These are old, stateful protocols with many extensions, versions and awkward syntax. Modern systems are built with REST APIs for a reason: they are much quicker for the developer to understand and build with (they are also way easier to load balance, due to the lack of state) + +I came back around to the idea of using the existing software, but this time I started looking for pre-configured systems. I discovered [iRedMail][iredmail] which claims to turn a fresh Debian or Ubuntu install into a working email server. This isn't bad, but I want to run a few other services from my Raspberry as well, and I'd rather not clobber them by re-installing Debian. + +This approach actually leads really neatly onto the last solution I tried, and the one I actually have working: [Mailu][mailu]. This project provides all the same open-source email components (postfix, dovecot), but pre-configured and packaged as [Docker][docker] images. I feel like this is the best approach for a few reasons: + +* You don't need a fresh Debian install, you just need a working Docker host. +* The hard configuration has been done for you. Just a single config file with a few easy to understand options is required. +* It's portable: copy over the mailu directory and the docker-compose.yml file to another machine, execute `docker-compose up -d` and it's back online with all the same accounts. +* An admin interface is included. +* It's open source so you can check if it conforms to current security practices, and modify it if you need to. +* The maintainer [kaiyou](https://github.com/kaiyou) is very helpful, and gratefully accepts pull requests. + +Although the project didn't work out of the box with Raspberry Pi this was a pretty easy thing to fix. I now maintain a permanent fork of mailu for Raspberry Pi over [here][mailu-rpi] + +[rpi]:https://www.raspberrypi.org/ +[dovecot-basic]:https://wiki.dovecot.org/BasicConfiguration +[ars-technica-guide]:https://arstechnica.com/information-technology/2014/02/how-to-run-your-own-e-mail-server-with-your-own-domain-part-1/ +[golang]:https://golang.org/ +[caddy]:https://caddyserver.com/ +[gomail]:https://github.com/MFAshby/gomail +[emersion]:https://github.com/emersion +[maddy]:https://github.com/emersion/maddy +[caddy-forum-non-http]:https://caddy.community/t/server-types-other-than-http/65/7 +[iredmail]:https://www.iredmail.org/ +[mailu]:https://github.com/Mailu/Mailu +[docker]:http://docker.io/ +[mailu-rpi]:https://github.com/MFAshby/mailu diff --git a/content/posts/2018-06-02-unicornpaint.md b/content/posts/2018-06-02-unicornpaint.md deleted file mode 100644 index b595e9a..0000000 --- a/content/posts/2018-06-02-unicornpaint.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -.title = "Unicorn Paint", -.author = "Martin Ashby", -.date = @date("2018-06-02T22:33:00+0100"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -See [unicornpaint] for details. I'll write about this later... - -![animated image](unicorn.gif) - -[unicornpaint]:https://unicorn.mfashby.net diff --git a/content/posts/2018-06-02-unicornpaint.smd b/content/posts/2018-06-02-unicornpaint.smd new file mode 100644 index 0000000..b595e9a --- /dev/null +++ b/content/posts/2018-06-02-unicornpaint.smd @@ -0,0 +1,13 @@ +--- +.title = "Unicorn Paint", +.author = "Martin Ashby", +.date = @date("2018-06-02T22:33:00+0100"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +See [unicornpaint] for details. I'll write about this later... + +![animated image](unicorn.gif) + +[unicornpaint]:https://unicorn.mfashby.net diff --git a/content/posts/2021-09-17-restart.md b/content/posts/2021-09-17-restart.md deleted file mode 100644 index 540d70c..0000000 --- a/content/posts/2021-09-17-restart.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -.title = "Restart", -.author = "Martin Ashby", -.date = @date("2021-09-17T23:41:39+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I'll restart blogging, likely in the form of micro-blogs restricted to just a few sentences. (like twitter) - -Upcoming tech topics: -* jekyll -> hugo switch -* mailu -> maddy switch -* alps webmail -* fediverse -* manjaro linux - -Non-tech topics: -* longboarding -* climbing for kids diff --git a/content/posts/2021-09-17-restart.smd b/content/posts/2021-09-17-restart.smd new file mode 100644 index 0000000..540d70c --- /dev/null +++ b/content/posts/2021-09-17-restart.smd @@ -0,0 +1,20 @@ +--- +.title = "Restart", +.author = "Martin Ashby", +.date = @date("2021-09-17T23:41:39+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I'll restart blogging, likely in the form of micro-blogs restricted to just a few sentences. (like twitter) + +Upcoming tech topics: +* jekyll -> hugo switch +* mailu -> maddy switch +* alps webmail +* fediverse +* manjaro linux + +Non-tech topics: +* longboarding +* climbing for kids diff --git a/content/posts/2021-09-18-maddy.md b/content/posts/2021-09-18-maddy.md deleted file mode 100644 index 86fadd5..0000000 --- a/content/posts/2021-09-18-maddy.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -.title = "Maddy", -.author = "Martin Ashby", -.date = @date("2021-09-18T22:05:32+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -Since my [last post on mail servers](https://mfashby.net/posts/2018-06-01-mailu/), the [maddy](https://maddy.email/) email server has advanced significantly, and now includes enough functionality to be a useful mail server adhering to current best practices. This includes DKIM, spam filtering with rspamd, virtual user management and more. - -I'm running this in conjunction with [alps](https://sr.ht/~migadu/alps/) webmail on my raspberry pi, and it's working well. - -I'm not yet using this as my daily driver account, but I might do in future. diff --git a/content/posts/2021-09-18-maddy.smd b/content/posts/2021-09-18-maddy.smd new file mode 100644 index 0000000..86fadd5 --- /dev/null +++ b/content/posts/2021-09-18-maddy.smd @@ -0,0 +1,13 @@ +--- +.title = "Maddy", +.author = "Martin Ashby", +.date = @date("2021-09-18T22:05:32+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +Since my [last post on mail servers](https://mfashby.net/posts/2018-06-01-mailu/), the [maddy](https://maddy.email/) email server has advanced significantly, and now includes enough functionality to be a useful mail server adhering to current best practices. This includes DKIM, spam filtering with rspamd, virtual user management and more. + +I'm running this in conjunction with [alps](https://sr.ht/~migadu/alps/) webmail on my raspberry pi, and it's working well. + +I'm not yet using this as my daily driver account, but I might do in future. diff --git a/content/posts/2021-09-19-longboard-setup.md b/content/posts/2021-09-19-longboard-setup.md deleted file mode 100644 index df035d4..0000000 --- a/content/posts/2021-09-19-longboard-setup.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -.title = "Longboard Setup", -.author = "Martin Ashby", -.date = @date("2021-09-19T10:20:49+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -![Longboard](longboard.jpg) - -I recently picked up longboarding. I enjoy snowboarding, but in the current pandemic + climate change it's looking less sustainable as a hobby, so I'm learning downhill longboarding. - -Current setup is pictured, links for individual items: - -* [Freebyrd Hiro](https://lushlongboards.com/buy/freebyrd-hiro/) complete -* Larger wheels are [cultron](https://shop.lushlongboards.com/collections/wheels/products/cult-wheels-cultron-74mm-white), which came with the board as a complete. These are great for cruising, but I am unable to make them slide. -* Smaller wheels fitted at the moment are [chronicle](https://shop.lushlongboards.com/collections/wheels/products/cult-wheels-chronicle-65mm-white). -* Gloves are [lush freeride](https://shop.lushlongboards.com/collections/gloves/products/freeride-gloves) -* [Bullet padset](https://vandemlongboardshop.co.uk/products/bullet-combo-standard-padset-adult) -* Helmet is just my bike helmet, but I should upgrade to a skate helmet soon for side impact protection. -* Adidas skate shoes. - -I've found the [longboarding subreddit](https://www.reddit.com/r/longboarding/) very informative, and I enjoy [downhill254](https://downhill254.com/)'s tutorial videos, as he includes some theory rather than just explaining how to do the moves. diff --git a/content/posts/2021-09-19-longboard-setup.smd b/content/posts/2021-09-19-longboard-setup.smd new file mode 100644 index 0000000..df035d4 --- /dev/null +++ b/content/posts/2021-09-19-longboard-setup.smd @@ -0,0 +1,23 @@ +--- +.title = "Longboard Setup", +.author = "Martin Ashby", +.date = @date("2021-09-19T10:20:49+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +![Longboard](longboard.jpg) + +I recently picked up longboarding. I enjoy snowboarding, but in the current pandemic + climate change it's looking less sustainable as a hobby, so I'm learning downhill longboarding. + +Current setup is pictured, links for individual items: + +* [Freebyrd Hiro](https://lushlongboards.com/buy/freebyrd-hiro/) complete +* Larger wheels are [cultron](https://shop.lushlongboards.com/collections/wheels/products/cult-wheels-cultron-74mm-white), which came with the board as a complete. These are great for cruising, but I am unable to make them slide. +* Smaller wheels fitted at the moment are [chronicle](https://shop.lushlongboards.com/collections/wheels/products/cult-wheels-chronicle-65mm-white). +* Gloves are [lush freeride](https://shop.lushlongboards.com/collections/gloves/products/freeride-gloves) +* [Bullet padset](https://vandemlongboardshop.co.uk/products/bullet-combo-standard-padset-adult) +* Helmet is just my bike helmet, but I should upgrade to a skate helmet soon for side impact protection. +* Adidas skate shoes. + +I've found the [longboarding subreddit](https://www.reddit.com/r/longboarding/) very informative, and I enjoy [downhill254](https://downhill254.com/)'s tutorial videos, as he includes some theory rather than just explaining how to do the moves. diff --git a/content/posts/2021-09-21-manjaro.md b/content/posts/2021-09-21-manjaro.md deleted file mode 100644 index 4299b9c..0000000 --- a/content/posts/2021-09-21-manjaro.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -.title = "Manjaro", -.author = "Martin Ashby", -.date = @date("2021-09-21T20:03:48+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I've used [Ubuntu](https://ubuntu.com/) linux for many years, but just recently it's started to become a bit more difficult due to proliferation of package managers. With the introduction of snap, flatpak, I'm never quite sure where I should be getting my software from. - -I've occasionally experimented with other distributions, but usually found them disadvantageous in some ways. For example, debian is quite stable, but doesn't usually ship the latest and greatest upstream software. - -I began to use [Manjaro](https://manjaro.org/) linux as it was the default operating system shipped on my [Pinebook Pro](https://www.pine64.org/pinebook-pro/), and I found the experience pretty refreshing. It's based on [Arch](https://archlinux.org/) linux but ships with a bit more pre-installed stuff. It also has great support for ARM based hardware. The Arch wiki and Arch User Repository are really great in my opinion, and with tools like `pamac` I can install a huge variety of stuff just with a few commands, even including building some software from source where there's no binary distribution. - -I'm probably going to experiment with [NixOS](https://nixos.org/) next, as I like the idea of reproducible installations. I'll likely try it on my Raspberry PI home server first. For bonus points, I'll also try a [ZFS](https://en.wikipedia.org/wiki/ZFS) based installation which should hopefully make backups a breeze. - diff --git a/content/posts/2021-09-21-manjaro.smd b/content/posts/2021-09-21-manjaro.smd new file mode 100644 index 0000000..4299b9c --- /dev/null +++ b/content/posts/2021-09-21-manjaro.smd @@ -0,0 +1,16 @@ +--- +.title = "Manjaro", +.author = "Martin Ashby", +.date = @date("2021-09-21T20:03:48+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I've used [Ubuntu](https://ubuntu.com/) linux for many years, but just recently it's started to become a bit more difficult due to proliferation of package managers. With the introduction of snap, flatpak, I'm never quite sure where I should be getting my software from. + +I've occasionally experimented with other distributions, but usually found them disadvantageous in some ways. For example, debian is quite stable, but doesn't usually ship the latest and greatest upstream software. + +I began to use [Manjaro](https://manjaro.org/) linux as it was the default operating system shipped on my [Pinebook Pro](https://www.pine64.org/pinebook-pro/), and I found the experience pretty refreshing. It's based on [Arch](https://archlinux.org/) linux but ships with a bit more pre-installed stuff. It also has great support for ARM based hardware. The Arch wiki and Arch User Repository are really great in my opinion, and with tools like `pamac` I can install a huge variety of stuff just with a few commands, even including building some software from source where there's no binary distribution. + +I'm probably going to experiment with [NixOS](https://nixos.org/) next, as I like the idea of reproducible installations. I'll likely try it on my Raspberry PI home server first. For bonus points, I'll also try a [ZFS](https://en.wikipedia.org/wiki/ZFS) based installation which should hopefully make backups a breeze. + diff --git a/content/posts/2021-09-26-pine64.md b/content/posts/2021-09-26-pine64.md deleted file mode 100644 index acee564..0000000 --- a/content/posts/2021-09-26-pine64.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -.title = "Pine64", -.author = "Martin Ashby", -.date = @date("2021-09-26T16:39:28+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I bought a [Pinebook Pro](https://www.pine64.org/pinebook-pro/) some while back, and I'm quite happy with it. It has a nice small form factor, decent display, nice shell, and reasonable battery life. When I first bought it software support was somewhat sketchy, however most linux distributions and even OpenBSD now have support for it, so I'm hoping I can keep using it for a number of years. I have even managed to do some dayjob (software development) work with it. - -I also bought the [Pinephone](https://www.pine64.org/pinephone/) but I've had much less success with this due to software not having caught up yet, and it's mostly consigned to my laptop bag these days. I might use it as a home server with a nice display in future. - -Finally I bought the [Pinetime](https://www.pine64.org/pinetime/) smartwatch. I bought the dev kit in the full knowledge the software wasn't there yet, but at only something like £25 it was quite attractive as a hobby project. The [Infinitime](https://github.com/JF002/Infinitime) operating system (which the pinetime is sold with) is quite accessible for me, and I hope to make some contributions to it in future. It doesn't quite replace my old pebble for looks or software yet, but the company and community are making progress. - -I'm really keen to try the [Pinenote](https://www.pine64.org/pinenote/) in future, as I really prefer looking at reflective rather than traditional transmissive backlit displays when I can, and it looks like a really nice crossover between tablet, laptop and e-reader. diff --git a/content/posts/2021-09-26-pine64.smd b/content/posts/2021-09-26-pine64.smd new file mode 100644 index 0000000..acee564 --- /dev/null +++ b/content/posts/2021-09-26-pine64.smd @@ -0,0 +1,15 @@ +--- +.title = "Pine64", +.author = "Martin Ashby", +.date = @date("2021-09-26T16:39:28+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I bought a [Pinebook Pro](https://www.pine64.org/pinebook-pro/) some while back, and I'm quite happy with it. It has a nice small form factor, decent display, nice shell, and reasonable battery life. When I first bought it software support was somewhat sketchy, however most linux distributions and even OpenBSD now have support for it, so I'm hoping I can keep using it for a number of years. I have even managed to do some dayjob (software development) work with it. + +I also bought the [Pinephone](https://www.pine64.org/pinephone/) but I've had much less success with this due to software not having caught up yet, and it's mostly consigned to my laptop bag these days. I might use it as a home server with a nice display in future. + +Finally I bought the [Pinetime](https://www.pine64.org/pinetime/) smartwatch. I bought the dev kit in the full knowledge the software wasn't there yet, but at only something like £25 it was quite attractive as a hobby project. The [Infinitime](https://github.com/JF002/Infinitime) operating system (which the pinetime is sold with) is quite accessible for me, and I hope to make some contributions to it in future. It doesn't quite replace my old pebble for looks or software yet, but the company and community are making progress. + +I'm really keen to try the [Pinenote](https://www.pine64.org/pinenote/) in future, as I really prefer looking at reflective rather than traditional transmissive backlit displays when I can, and it looks like a really nice crossover between tablet, laptop and e-reader. diff --git a/content/posts/2021-09-29-bike.md b/content/posts/2021-09-29-bike.md deleted file mode 100644 index 0dc06e5..0000000 --- a/content/posts/2021-09-29-bike.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -.title = "Bike", -.author = "Martin Ashby", -.date = @date("2021-10-01T12:27:26+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I recently refurbished my bike for use as a commuter. I work at home, but I need to commute my daughter to nursery a couple of days a week. It's also handy to be able to increase my range without having to use the car, as traffic around the area can get bad. - -The bike is an old Claude Butler with pink bear-trap pedals. I bought it second hand ~10 years ago so there's no way I can find links for original parts. I haven't ridden it for around 2 years, so it needed some TLC. This included general disassembly and clean-up; and a new chain courtesy of the local bike shop as the old one had stretched badly. The cassettes were OK though, and don't seem to have been damaged by the chain wear. I've fitted [fire xc pro panaracers](https://www.panaracer.co.uk/shop-c1/tyres-c34/mtb-tyres-c4/panaracer-fire-xc-pro-tubeless-compatible-folding-tyre-p39) as I wanted a retro look with coloured tyres rather than plain black. These have great grip and I like how they look, but I've struggled to get them to fit nicely around the valve portion of the wheel. This leaves a bump in the tyre which can make the ride slightly bumpy at speed. - -For my daughter, I fitted an [Oxford little explorer](https://www.argos.co.uk/product/4848653) tube top. I had to adapt this slightly as my brake and gear cables run along the top of the same tube. I divided the rubber buffer in two to go either side of the cables and it seems to work OK. As well as this, my neighbour gave me a stem-fitting back seat that their son had outgrown. This setup works very well, as my daughter can ride upfront when we're going on rougher terrain or if she just wants a more exciting ride, and on the back seat when she's tired. We can also use the back seat for luggage if necessary. - -Probably the next thing I'll need to upgrade are some lights. I bought some small silicone ones but these quickly died as they allowed water into the battery compartment. I'll likely get some helmet mounted ones as well as ones for the actual bike, and reflective strips for the back seat to try to maximise visibility. After that I would also like to upgrade the brakes. I've got rim-brakes with fairly large pads, but something with a bit more stopping power would be nice. - -![Bike](bike.jpg) diff --git a/content/posts/2021-09-29-bike.smd b/content/posts/2021-09-29-bike.smd new file mode 100644 index 0000000..0dc06e5 --- /dev/null +++ b/content/posts/2021-09-29-bike.smd @@ -0,0 +1,17 @@ +--- +.title = "Bike", +.author = "Martin Ashby", +.date = @date("2021-10-01T12:27:26+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I recently refurbished my bike for use as a commuter. I work at home, but I need to commute my daughter to nursery a couple of days a week. It's also handy to be able to increase my range without having to use the car, as traffic around the area can get bad. + +The bike is an old Claude Butler with pink bear-trap pedals. I bought it second hand ~10 years ago so there's no way I can find links for original parts. I haven't ridden it for around 2 years, so it needed some TLC. This included general disassembly and clean-up; and a new chain courtesy of the local bike shop as the old one had stretched badly. The cassettes were OK though, and don't seem to have been damaged by the chain wear. I've fitted [fire xc pro panaracers](https://www.panaracer.co.uk/shop-c1/tyres-c34/mtb-tyres-c4/panaracer-fire-xc-pro-tubeless-compatible-folding-tyre-p39) as I wanted a retro look with coloured tyres rather than plain black. These have great grip and I like how they look, but I've struggled to get them to fit nicely around the valve portion of the wheel. This leaves a bump in the tyre which can make the ride slightly bumpy at speed. + +For my daughter, I fitted an [Oxford little explorer](https://www.argos.co.uk/product/4848653) tube top. I had to adapt this slightly as my brake and gear cables run along the top of the same tube. I divided the rubber buffer in two to go either side of the cables and it seems to work OK. As well as this, my neighbour gave me a stem-fitting back seat that their son had outgrown. This setup works very well, as my daughter can ride upfront when we're going on rougher terrain or if she just wants a more exciting ride, and on the back seat when she's tired. We can also use the back seat for luggage if necessary. + +Probably the next thing I'll need to upgrade are some lights. I bought some small silicone ones but these quickly died as they allowed water into the battery compartment. I'll likely get some helmet mounted ones as well as ones for the actual bike, and reflective strips for the back seat to try to maximise visibility. After that I would also like to upgrade the brakes. I've got rim-brakes with fairly large pads, but something with a bit more stopping power would be nice. + +![Bike](bike.jpg) diff --git a/content/posts/2021-09-29-recipe.md b/content/posts/2021-09-29-recipe.md deleted file mode 100644 index fa443aa..0000000 --- a/content/posts/2021-09-29-recipe.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -.title = "Recipe", -.author = "Martin Ashby", -.date = @date("2021-09-29T22:56:01+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I found [plainoldrecipe](https://github.com/poundifdef/plainoldrecipe) a while back, I find it really handy for some recipe sites which are full of cookie banners and ads, it makes them much easier to read on a phone or small laptop while I'm actually trying to cook. - -I'm hosting it myself [here](https://recipe.mfashby.net) as the author's site is sometimes down. - -A cool extension might be some way to send the recipe to my kindle for easier reading & offline usage. - diff --git a/content/posts/2021-09-29-recipe.smd b/content/posts/2021-09-29-recipe.smd new file mode 100644 index 0000000..fa443aa --- /dev/null +++ b/content/posts/2021-09-29-recipe.smd @@ -0,0 +1,14 @@ +--- +.title = "Recipe", +.author = "Martin Ashby", +.date = @date("2021-09-29T22:56:01+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I found [plainoldrecipe](https://github.com/poundifdef/plainoldrecipe) a while back, I find it really handy for some recipe sites which are full of cookie banners and ads, it makes them much easier to read on a phone or small laptop while I'm actually trying to cook. + +I'm hosting it myself [here](https://recipe.mfashby.net) as the author's site is sometimes down. + +A cool extension might be some way to send the recipe to my kindle for easier reading & offline usage. + diff --git a/content/posts/2021-10-01-blog.md b/content/posts/2021-10-01-blog.md deleted file mode 100644 index 32d595b..0000000 --- a/content/posts/2021-10-01-blog.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -.title = "Blog", -.author = "Martin Ashby", -.date = @date("2021-10-01T19:34:15+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I originally started this blog using [Jekyll](https://jekyllrb.com/), but I've since switched to using [hugo](https://gohugo.io/) after I found it simpler to install and use (`pamac install hugo` on manjaro linux). - -The content is stored on my laptop and on [github](https://github.com/MFAshby/mfashby.net). I have a cron job on my raspberry pi which pulls the latest changes and builds the site every 15 minutes, so changes are automatically published. - -I could improve this setup slightly using [GitHub webhooks](https://docs.github.com/en/developers/webhooks-and-events/webhooks/about-webhooks) to detect the changes immediately and refresh rather than polling. - diff --git a/content/posts/2021-10-01-blog.smd b/content/posts/2021-10-01-blog.smd new file mode 100644 index 0000000..32d595b --- /dev/null +++ b/content/posts/2021-10-01-blog.smd @@ -0,0 +1,14 @@ +--- +.title = "Blog", +.author = "Martin Ashby", +.date = @date("2021-10-01T19:34:15+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I originally started this blog using [Jekyll](https://jekyllrb.com/), but I've since switched to using [hugo](https://gohugo.io/) after I found it simpler to install and use (`pamac install hugo` on manjaro linux). + +The content is stored on my laptop and on [github](https://github.com/MFAshby/mfashby.net). I have a cron job on my raspberry pi which pulls the latest changes and builds the site every 15 minutes, so changes are automatically published. + +I could improve this setup slightly using [GitHub webhooks](https://docs.github.com/en/developers/webhooks-and-events/webhooks/about-webhooks) to detect the changes immediately and refresh rather than polling. + diff --git a/content/posts/2021-10-06-clojure.md b/content/posts/2021-10-06-clojure.md deleted file mode 100644 index 14d9770..0000000 --- a/content/posts/2021-10-06-clojure.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -.title = "Clojure", -.author = "Martin Ashby", -.date = @date("2021-10-06T21:35:37+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I'm learning [Clojure](https://clojure.org) on the basis that you should learn something that will change your way of thinking. I've previously stuck to C-family languages, and I work professionally with Java. - -To do this I'm working through [Clojure for the Brave and True](https://nostarch.com/clojure), which has a good balance of whimsy (it's not so dry as other technical books) and exercises vs plain reading material. - -I'm planning to build a slack clone using full-stack clojure, since I learn faster if I get stuck in and try something. - diff --git a/content/posts/2021-10-06-clojure.smd b/content/posts/2021-10-06-clojure.smd new file mode 100644 index 0000000..14d9770 --- /dev/null +++ b/content/posts/2021-10-06-clojure.smd @@ -0,0 +1,14 @@ +--- +.title = "Clojure", +.author = "Martin Ashby", +.date = @date("2021-10-06T21:35:37+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I'm learning [Clojure](https://clojure.org) on the basis that you should learn something that will change your way of thinking. I've previously stuck to C-family languages, and I work professionally with Java. + +To do this I'm working through [Clojure for the Brave and True](https://nostarch.com/clojure), which has a good balance of whimsy (it's not so dry as other technical books) and exercises vs plain reading material. + +I'm planning to build a slack clone using full-stack clojure, since I learn faster if I get stuck in and try something. + diff --git a/content/posts/2021-10-30-openbsd.md b/content/posts/2021-10-30-openbsd.md deleted file mode 100644 index 5551532..0000000 --- a/content/posts/2021-10-30-openbsd.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -.title = "OpenBSD", -.author = "Martin Ashby", -.date = @date("2021-10-30T20:25:43+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I've tried installing & using [OpenBSD](https://openbsd.org/) 7.0 on my Pinebook Pro. I've previously used OpenBSD on a small VPS just to try it out, and I was quite impressed. - -Unfortunately installing on the pinebook has been significantly more rocky than installing various linux flavours, and the performance isn't quite good enough for me to continue using it. I hope to revisit in future as I like the philosophy of the project. Support for the pinebook and aarch64 hardware in general seems quite new for OpenBSD so it's likely to continue to mature as more knowledgable users try it out and fix things. - -I'll write up my installation process, with gotchas, as there were a couple. - -## Prerequisites -I started with a pinebook running Manjaro ARM installed to the eMMC. I had a couple of 32GB micro SD cards available, a few USB mass storage devices to hand, and the [USB serial converter](https://pine64.com/product/pinebook-pinephone-pinetab-serial-console/) for the pinebook pro. I have another regular x86 laptop running Manjaro also, with SD card reader. The USB serial converter is necessary since the OpenBSD installer can't drive the display. - -I wanted OpenBSD installed to the eMMC device. - -## Process -0. Back up all your stuff. This process will wipe your entire pinebook. -1. Read the [official installation instructions](https://ftp.openbsd.org/pub/OpenBSD/snapshots/arm64/INSTALL.arm64) -2. Read [this blog post](https://xosc.org/pinebookpro.html) about installing on an older version. I find narratives like this easier to read and follow than the official docs. - -## Create the installer -3. Download all the files from [this FTP folder](https://ftp.openbsd.org/pub/OpenBSD/snapshots/arm64/). You need mostly all of them, [mirrors](https://www.openbsd.org/ftp.html) are available around the world. -4. Use dd to copy the install70.img to an empty SD card -``` -sudo dd if=install70.img of=/dev/mmcblk2 bs=4M conv=fsync status=progress -``` -5. Copy everything else from that folder to a standard USB memory stick. This is important because unless you have a USB ethernet, you won't be able to download those files during the installation process, as the WiFi chip isn't supported. -6. Download and unzip the [u-boot package](https://ftp.openbsd.org/pub/OpenBSD/snapshots/packages/aarch64/u-boot-aarch64-2021.10p0.tgz). The u-boot that Manjaro ARM installs isn't capable of booting OpenBSD. -7. Use dd to copy in the u-boot files to the appropriate location on the SD card -``` -sudo dd if=share/u-boot/pinebook-pro-rk3399/idbloader.img of=/dev/mmcblk2 seek=64 -sudo dd if=share/u-boot/pinebook-pro-rk3399/u-boot.itb of=/dev/mmcbkl2 seek=16384 -sync -``` -8. Download all the files from [this FTP folder](http://firmware.openbsd.org/firmware/7.0/) and copy them all to the standard USB memory stick in a subfolder (e.g. firmware). This is required additional non-free firmware to get the wifi working. - -## Wipe the eMMC -9. The u-boot that Manjaro ARM installs isn't capable of booting OpenBSD. It hangs on a line about 'ochi0' and won't proceed. So, you need to wipe u-boot off the eMMC before the installer will boot! To do this, take another micro SD card, write your favourite supported linux build for the pinebook pro, and use gparted to make a new parttion table for the eMMC card. - -## Enable USB serial interface -10. Turn off your Pinebook, follow the [disassembly guide](https://wiki.pine64.org/wiki/Pinebook_Pro#Mainboard_Switches_and_Buttons) and toggle the headphone / serial console switch. Put the case back together. Try not to lose the screws. - -## Install OpenBSD -11. Insert the SD card with OpenBSD. -12. Connect the USB serial to your headphone jack and another computer (mine is a x86 laptop running Manjaro) -13. Start up `screen` or similar program to connect to the serial interface -``` -sudo screen /dev/ttyUSB0 115200 -``` -14. Connect the USB mass storage device with other files on it. -15. Power on the pinebook. If everything went well, you should see OpenBSD installer prompt eventually in your screen session. -16. Follow the on-screen instructions to install. I had to choose a few non-default options: - -a. Change the install disk to sd1. You can use ? to show disk info, sd1 was the eMMC card for me. - -b. When prompted to install filesets, choose 'disk' rather than network, 'no' for 'is the disk already mounted' and 'sd2' for the disk. This corresponded to my USB mass storage device. - -17. When the install is complete, reboot. I had to hold the power button, it seems OpenBSD can't trigger the actual power off. You need to leave the SD card in, as u-boot isn't installed to the eMMC module! - -## Install firmware and u-boot -18. Power on the pinebook again. Login as root over your serial console connection. -19. Mount the USB mass storage, something like `mount /dev/sd2i /mnt`, and use [fw_update](https://man.openbsd.org/fw_update) with -p option to use the firmware files on the USB rather than try to get them from the internet. -20. Configure your wireless card by adding [/etc/hostname.bwfm0](https://man.openbsd.org/hostname.if.5) file with the following content -``` -nwid wpakey -inet autoconf -``` -21. Reboot. You should now have access to the internet to install stuff! -22. Install u-boot-aarch64 package `pkg_add u-boot-aarch64` and run through similar instructions as before to write the files to the appropriate place on the eMMC card this time. Note the files are stored in /usr/local/share... and the eMMC card is now something like /dev/rsd0! -23. Reboot again, this time removing the SD card. You should be able to boot without it now. - -## Enable graphics -24. Enable [xenodm](https://man.openbsd.org/xenodm.1) with `rcctl enable xenodm` -25. Reboot. You should now get graphical login! - -From here the OpenBSD manual pages and various guides/blogs should help you build the system you want. - -I installed gnome as my desktop, but this has proven too slow without hardware acceleration (which OpenBSD still lacks on Pinebook Pro) - -I hope these instructions were useful, if you have a comment or correction please let me know via martin (at) mfashby.net. diff --git a/content/posts/2021-10-30-openbsd.smd b/content/posts/2021-10-30-openbsd.smd new file mode 100644 index 0000000..5551532 --- /dev/null +++ b/content/posts/2021-10-30-openbsd.smd @@ -0,0 +1,84 @@ +--- +.title = "OpenBSD", +.author = "Martin Ashby", +.date = @date("2021-10-30T20:25:43+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I've tried installing & using [OpenBSD](https://openbsd.org/) 7.0 on my Pinebook Pro. I've previously used OpenBSD on a small VPS just to try it out, and I was quite impressed. + +Unfortunately installing on the pinebook has been significantly more rocky than installing various linux flavours, and the performance isn't quite good enough for me to continue using it. I hope to revisit in future as I like the philosophy of the project. Support for the pinebook and aarch64 hardware in general seems quite new for OpenBSD so it's likely to continue to mature as more knowledgable users try it out and fix things. + +I'll write up my installation process, with gotchas, as there were a couple. + +## Prerequisites +I started with a pinebook running Manjaro ARM installed to the eMMC. I had a couple of 32GB micro SD cards available, a few USB mass storage devices to hand, and the [USB serial converter](https://pine64.com/product/pinebook-pinephone-pinetab-serial-console/) for the pinebook pro. I have another regular x86 laptop running Manjaro also, with SD card reader. The USB serial converter is necessary since the OpenBSD installer can't drive the display. + +I wanted OpenBSD installed to the eMMC device. + +## Process +0. Back up all your stuff. This process will wipe your entire pinebook. +1. Read the [official installation instructions](https://ftp.openbsd.org/pub/OpenBSD/snapshots/arm64/INSTALL.arm64) +2. Read [this blog post](https://xosc.org/pinebookpro.html) about installing on an older version. I find narratives like this easier to read and follow than the official docs. + +## Create the installer +3. Download all the files from [this FTP folder](https://ftp.openbsd.org/pub/OpenBSD/snapshots/arm64/). You need mostly all of them, [mirrors](https://www.openbsd.org/ftp.html) are available around the world. +4. Use dd to copy the install70.img to an empty SD card +``` +sudo dd if=install70.img of=/dev/mmcblk2 bs=4M conv=fsync status=progress +``` +5. Copy everything else from that folder to a standard USB memory stick. This is important because unless you have a USB ethernet, you won't be able to download those files during the installation process, as the WiFi chip isn't supported. +6. Download and unzip the [u-boot package](https://ftp.openbsd.org/pub/OpenBSD/snapshots/packages/aarch64/u-boot-aarch64-2021.10p0.tgz). The u-boot that Manjaro ARM installs isn't capable of booting OpenBSD. +7. Use dd to copy in the u-boot files to the appropriate location on the SD card +``` +sudo dd if=share/u-boot/pinebook-pro-rk3399/idbloader.img of=/dev/mmcblk2 seek=64 +sudo dd if=share/u-boot/pinebook-pro-rk3399/u-boot.itb of=/dev/mmcbkl2 seek=16384 +sync +``` +8. Download all the files from [this FTP folder](http://firmware.openbsd.org/firmware/7.0/) and copy them all to the standard USB memory stick in a subfolder (e.g. firmware). This is required additional non-free firmware to get the wifi working. + +## Wipe the eMMC +9. The u-boot that Manjaro ARM installs isn't capable of booting OpenBSD. It hangs on a line about 'ochi0' and won't proceed. So, you need to wipe u-boot off the eMMC before the installer will boot! To do this, take another micro SD card, write your favourite supported linux build for the pinebook pro, and use gparted to make a new parttion table for the eMMC card. + +## Enable USB serial interface +10. Turn off your Pinebook, follow the [disassembly guide](https://wiki.pine64.org/wiki/Pinebook_Pro#Mainboard_Switches_and_Buttons) and toggle the headphone / serial console switch. Put the case back together. Try not to lose the screws. + +## Install OpenBSD +11. Insert the SD card with OpenBSD. +12. Connect the USB serial to your headphone jack and another computer (mine is a x86 laptop running Manjaro) +13. Start up `screen` or similar program to connect to the serial interface +``` +sudo screen /dev/ttyUSB0 115200 +``` +14. Connect the USB mass storage device with other files on it. +15. Power on the pinebook. If everything went well, you should see OpenBSD installer prompt eventually in your screen session. +16. Follow the on-screen instructions to install. I had to choose a few non-default options: + +a. Change the install disk to sd1. You can use ? to show disk info, sd1 was the eMMC card for me. + +b. When prompted to install filesets, choose 'disk' rather than network, 'no' for 'is the disk already mounted' and 'sd2' for the disk. This corresponded to my USB mass storage device. + +17. When the install is complete, reboot. I had to hold the power button, it seems OpenBSD can't trigger the actual power off. You need to leave the SD card in, as u-boot isn't installed to the eMMC module! + +## Install firmware and u-boot +18. Power on the pinebook again. Login as root over your serial console connection. +19. Mount the USB mass storage, something like `mount /dev/sd2i /mnt`, and use [fw_update](https://man.openbsd.org/fw_update) with -p option to use the firmware files on the USB rather than try to get them from the internet. +20. Configure your wireless card by adding [/etc/hostname.bwfm0](https://man.openbsd.org/hostname.if.5) file with the following content +``` +nwid wpakey +inet autoconf +``` +21. Reboot. You should now have access to the internet to install stuff! +22. Install u-boot-aarch64 package `pkg_add u-boot-aarch64` and run through similar instructions as before to write the files to the appropriate place on the eMMC card this time. Note the files are stored in /usr/local/share... and the eMMC card is now something like /dev/rsd0! +23. Reboot again, this time removing the SD card. You should be able to boot without it now. + +## Enable graphics +24. Enable [xenodm](https://man.openbsd.org/xenodm.1) with `rcctl enable xenodm` +25. Reboot. You should now get graphical login! + +From here the OpenBSD manual pages and various guides/blogs should help you build the system you want. + +I installed gnome as my desktop, but this has proven too slow without hardware acceleration (which OpenBSD still lacks on Pinebook Pro) + +I hope these instructions were useful, if you have a comment or correction please let me know via martin (at) mfashby.net. diff --git a/content/posts/2021-11-05-postgres-query-rewrite.md b/content/posts/2021-11-05-postgres-query-rewrite.md deleted file mode 100644 index d3ce7ea..0000000 --- a/content/posts/2021-11-05-postgres-query-rewrite.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -.title = "Postgres Query Rewrite", -.author = "Martin Ashby", -.date = @date("2021-11-05T11:57:12Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -Recently at work, I needed to be able to rewrite some [postgresql](https://www.postgresql.org/) queries which were coming from a closed-source application in order to integrate the app into our own system testing setup. Specifically I needed to replace instances of `current_timestamp` with invocation of `now()` function. - -I found a couple of options to do this: -1. [pgbouncer-rr](https://github.com/awslabs/pgbouncer-rr-patch) is a _patch_ for [pgbouncer](https://www.pgbouncer.org/), initially written by AWS labs, which extends pgbouncer to include rewrite and rerouting capability. -2. [pg_query_rewrite](https://github.com/pierreforstmann/pg_query_rewrite) is an _extension_ for postgres, which supports substitution of an entire matching query with another one. - -Unfortunately I hit some roadblocks with each. `pg_query_rewrite` simply wasn't flexible enough. I needed to do a string substitution on the query, not entire query replacement as I didn't have the exact set of every query the application would issue. Also providers of managed postgresql instances like Google Cloud or AWS won't let you install your own extensions. `pgbouncer-rr` was moderately difficult to configure given that I only wanted a single feature (rewriting) and none of the usual things pgbouncer is used for (connection pooling, load balancing). - -In the end, I found a neat library [pgproto3](https://github.com/jackc/pgproto3) which implements the postgresql wire format and can be used to write both a client and server! I used this to write [an application](https://github.com/patientsknowbest/pg-rewrite-proxy) that can act as a proxy to a postgresql server and will rewrite the queries before forwarding them. The proxy approach seems more flexible than an extension as it can be bundled either on the application server, or on the database server, or somewhere in-between depending on the requirement. - -At the moment this application only supports simple string replacement, but I hope to extend it with [LUA](https://www.lua.org/) support soon for arbitrary query rewriting. diff --git a/content/posts/2021-11-05-postgres-query-rewrite.smd b/content/posts/2021-11-05-postgres-query-rewrite.smd new file mode 100644 index 0000000..d3ce7ea --- /dev/null +++ b/content/posts/2021-11-05-postgres-query-rewrite.smd @@ -0,0 +1,19 @@ +--- +.title = "Postgres Query Rewrite", +.author = "Martin Ashby", +.date = @date("2021-11-05T11:57:12Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +Recently at work, I needed to be able to rewrite some [postgresql](https://www.postgresql.org/) queries which were coming from a closed-source application in order to integrate the app into our own system testing setup. Specifically I needed to replace instances of `current_timestamp` with invocation of `now()` function. + +I found a couple of options to do this: +1. [pgbouncer-rr](https://github.com/awslabs/pgbouncer-rr-patch) is a _patch_ for [pgbouncer](https://www.pgbouncer.org/), initially written by AWS labs, which extends pgbouncer to include rewrite and rerouting capability. +2. [pg_query_rewrite](https://github.com/pierreforstmann/pg_query_rewrite) is an _extension_ for postgres, which supports substitution of an entire matching query with another one. + +Unfortunately I hit some roadblocks with each. `pg_query_rewrite` simply wasn't flexible enough. I needed to do a string substitution on the query, not entire query replacement as I didn't have the exact set of every query the application would issue. Also providers of managed postgresql instances like Google Cloud or AWS won't let you install your own extensions. `pgbouncer-rr` was moderately difficult to configure given that I only wanted a single feature (rewriting) and none of the usual things pgbouncer is used for (connection pooling, load balancing). + +In the end, I found a neat library [pgproto3](https://github.com/jackc/pgproto3) which implements the postgresql wire format and can be used to write both a client and server! I used this to write [an application](https://github.com/patientsknowbest/pg-rewrite-proxy) that can act as a proxy to a postgresql server and will rewrite the queries before forwarding them. The proxy approach seems more flexible than an extension as it can be bundled either on the application server, or on the database server, or somewhere in-between depending on the requirement. + +At the moment this application only supports simple string replacement, but I hope to extend it with [LUA](https://www.lua.org/) support soon for arbitrary query rewriting. diff --git a/content/posts/2021-11-09-longboard-2.md b/content/posts/2021-11-09-longboard-2.md deleted file mode 100644 index a87acc7..0000000 --- a/content/posts/2021-11-09-longboard-2.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -.title = "Longboard 2", -.author = "Martin Ashby", -.date = @date("2021-11-09T21:56:41Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -Since my last post on longboarding, I've been learning to [push up slide](https://downhill254.com/how-to-push-up-slide-longboarding/) and [coleman slide](https://downhill254.com/coleman-slide-for-longboard-downhill-pendulum-slide/). These are essential skills to control your speed so you can safely tackle steeper and longer hills. - -I've also made a couple of hardware changes -- switched to [powell peralta snakes](https://newtons-shred.co.uk/shop/skateboards/wheels/cruiser-filmer/powell-peralta-snakes-red-66mm-75a/), following many many reviews on [reddit](https://teddit.net/r/longboarding) -- added [freebrake brake soles](https://newtons-shred.co.uk/shop/safety/other/footbraking-sole/freebrake-longboard-skateboard-footbraking-sole-4mm-pair/) to my shoes. I had nearly worn through the heel and toe on my right foot from frequent braking. These appear to be up-cycled car tyres! - - - diff --git a/content/posts/2021-11-09-longboard-2.smd b/content/posts/2021-11-09-longboard-2.smd new file mode 100644 index 0000000..3babf28 --- /dev/null +++ b/content/posts/2021-11-09-longboard-2.smd @@ -0,0 +1,17 @@ +--- +.title = "Longboard 2", +.author = "Martin Ashby", +.date = @date("2021-11-09T21:56:41Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +Since my last post on longboarding, I've been learning to [push up slide](https://downhill254.com/how-to-push-up-slide-longboarding/) and [coleman slide](https://downhill254.com/coleman-slide-for-longboard-downhill-pendulum-slide/). These are essential skills to control your speed so you can safely tackle steeper and longer hills. + +I've also made a couple of hardware changes +- switched to [powell peralta snakes](https://newtons-shred.co.uk/shop/skateboards/wheels/cruiser-filmer/powell-peralta-snakes-red-66mm-75a/), following many many reviews on [reddit](https://teddit.net/r/longboarding) +- added [freebrake brake soles](https://newtons-shred.co.uk/shop/safety/other/footbraking-sole/freebrake-longboard-skateboard-footbraking-sole-4mm-pair/) to my shoes. I had nearly worn through the heel and toe on my right foot from frequent braking. These appear to be up-cycled car tyres! + +```=html + +``` diff --git a/content/posts/2021-11-14-backups.md b/content/posts/2021-11-14-backups.md deleted file mode 100644 index 396dcb3..0000000 --- a/content/posts/2021-11-14-backups.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -.title = "Backups", -.author = "Martin Ashby", -.date = @date("2021-11-14T11:12:44Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I've recently setup a full system backup for my raspberry pi home server, backing up to my NAS over NFS. Working backups give me the confidence to use it for more critical things like email, calendar and contacts. - -I've used [restic](https://github.com/restic/restic) as it does convenient, password-encrypted, differential backups to a variety of backends. - -I've set it up with a systemd timer to trigger it. The script I've written shuts down all services so the file system isn't changing too much underneath while the backup is working, mounts the backup location, does the backup, then unmounts the backup again before restarting the rest of the system. I think it's important to disconnect the backup location during normal operation to prevent damage to backups should some bad command run, like `rm -rf /`. - -I've tested restoring the whole system to a new SD card, and while it's not perfect, it does work with only minor adjustments after restore. - -In future I'll probably copy the backup to an offsite system like [backblaze B2](https://www.backblaze.com/b2/cloud-storage.html), or I'll set up an arrangement with a friend who also has some space on a NAS and a decent 'net connection. I'll also configure restic to prune old backups to save on space. diff --git a/content/posts/2021-11-14-backups.smd b/content/posts/2021-11-14-backups.smd new file mode 100644 index 0000000..396dcb3 --- /dev/null +++ b/content/posts/2021-11-14-backups.smd @@ -0,0 +1,17 @@ +--- +.title = "Backups", +.author = "Martin Ashby", +.date = @date("2021-11-14T11:12:44Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I've recently setup a full system backup for my raspberry pi home server, backing up to my NAS over NFS. Working backups give me the confidence to use it for more critical things like email, calendar and contacts. + +I've used [restic](https://github.com/restic/restic) as it does convenient, password-encrypted, differential backups to a variety of backends. + +I've set it up with a systemd timer to trigger it. The script I've written shuts down all services so the file system isn't changing too much underneath while the backup is working, mounts the backup location, does the backup, then unmounts the backup again before restarting the rest of the system. I think it's important to disconnect the backup location during normal operation to prevent damage to backups should some bad command run, like `rm -rf /`. + +I've tested restoring the whole system to a new SD card, and while it's not perfect, it does work with only minor adjustments after restore. + +In future I'll probably copy the backup to an offsite system like [backblaze B2](https://www.backblaze.com/b2/cloud-storage.html), or I'll set up an arrangement with a friend who also has some space on a NAS and a decent 'net connection. I'll also configure restic to prune old backups to save on space. diff --git a/content/posts/2021-12-04-contacts.md b/content/posts/2021-12-04-contacts.md deleted file mode 100644 index 08f18f6..0000000 --- a/content/posts/2021-12-04-contacts.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -.title = "Contacts", -.author = "Martin Ashby", -.date = @date("2021-12-04T15:05:47Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I'm now using [radicale](https://radicale.org/) for calendar and contacts. This was very easy to install and configure in manjaro linux. I'm using this in conjunction with [radicale-imap](https://github.com/r3c/radicale-imap) plugin for authentication. Eventually I might look at an SSO solution for the variety of services I have installed on my server. - -Google supports exporting contacts in vcard format, and calendar events in ics format, both of which can be imported in a capable calendar or contacts app in android. - -Radicale depends on python, which is OK but possibly more susceptible to python environment changes than I would prefer. I had looked at [fennel](https://github.com/swordlordcodingcrew/fennel/) server which is implemented in golang, but as yet this isn't compatible with Dav5X on Android due to incomplete implementation. - diff --git a/content/posts/2021-12-04-contacts.smd b/content/posts/2021-12-04-contacts.smd new file mode 100644 index 0000000..08f18f6 --- /dev/null +++ b/content/posts/2021-12-04-contacts.smd @@ -0,0 +1,14 @@ +--- +.title = "Contacts", +.author = "Martin Ashby", +.date = @date("2021-12-04T15:05:47Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I'm now using [radicale](https://radicale.org/) for calendar and contacts. This was very easy to install and configure in manjaro linux. I'm using this in conjunction with [radicale-imap](https://github.com/r3c/radicale-imap) plugin for authentication. Eventually I might look at an SSO solution for the variety of services I have installed on my server. + +Google supports exporting contacts in vcard format, and calendar events in ics format, both of which can be imported in a capable calendar or contacts app in android. + +Radicale depends on python, which is OK but possibly more susceptible to python environment changes than I would prefer. I had looked at [fennel](https://github.com/swordlordcodingcrew/fennel/) server which is implemented in golang, but as yet this isn't compatible with Dav5X on Android due to incomplete implementation. + diff --git a/content/posts/2021-12-28-chat-server-protocol.md b/content/posts/2021-12-28-chat-server-protocol.md deleted file mode 100644 index 4d8e084..0000000 --- a/content/posts/2021-12-28-chat-server-protocol.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -.title = "Chat Server Protocol", -.author = "Martin Ashby", -.date = @date("2021-12-28T22:22:01Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I wrote a previous post about [clojure](/posts/2021-10-06-clojure/) where I expressed an intent to write a slack clone using the language. Like most ideas, this didn't go anywhere, however it did spawn a new idea: Chat Server Protocol. - -There are several different popular messaging platforms, each used by different groups of people I know, for example WhatsApp, Telegram, Signal, Facebook Messenger, Slack & Discord. Having to install each one and learn the particulars of it's user interface can be tiresome. Some of them only cater for certain platforms via their official apps, e.g. WhatsApp is only available for iOS, Android and KaiOS. - -Naturally some people have tried to solve this problem already and provide a universal chat client. Here are some projects I know about and what their approach is: - -- [meetfranz](https://meetfranz.com/) is embedding the web UI of each chat platform into a single electron app. -- [pidgin](https://pidgin.im/) is running a plugin system where contributors can write a shared library to support a new platform. -- [beeper](https://beeper.com) is bridging messaging platforms on the server side and using [matrix](https://matrix.org) as a central system. - -All of these approaches have some drawbacks. For example, franz isn't saving you from learning the web UI of each platform (citation needed, I need to try franz for longer first). Beeper relies on a hosted service running the matrix server and bridges, and you must also trust them to hold credentials to the various platforms. - -I prefer pidgin's approach: a plugin system. The code is split into several pieces: libpurple is the 'core' which handles the basic functions of a messenger app. There are many 'plugins' which link into the core to provide implementations for different platforms. There are several UI programs which then build on libpurple to provide a user interface. Pidgin is one of these, and it provides an interface using GTK+. - -This approach lowers the barrier to entry for integrating new messaging platforms, because the developer does not _also_ have to write the user interface. It also lowers the barrier to entry for writing new user interfaces, since the developer does not also have to write the backend integration to the messaging platform. However, the most significant downside is that plugins are called as shared libraries. This means plugin developers are restricted to C, C++ or other languages that can follow C function calling conventions. Theoretically most languages can do this, however it is often impractical, for example [calling java functions from C](https://nachtimwald.com/2017/06/17/calling-java-from-c/) involves booting up a JVM from your C code. - -A similar problem has recently been solved in the field of IDE's (Integrated Development Environments): Language Server Protocol is a protocol which defines all the 'core' operations of an IDE. Requests are made by a 'client' to a 'server' via IPC (Inter-process communication) mechanisms such as standard streams (stdin/out), TCP or unix sockets or named pipes. - -I propose the same technique could be applied to chat applications: define a 'Chat Server Protocol' which encapsulates all the core operations of a chat app. Clients and servers can then both be written against this protocol enabling far greater interoperability. Since the only requirement for implementing the protocol is some IPC mechanism, which every practical programming langauge supports, then this provides much greater implementation flexibility compared to libpurple. An additional benefit is that crashes in the server implementation can be handled more gracefully by the client, since they are in different processes a crash in the server will not automatically kill the client. - -Some potential problems with this approach: -- multi-processing is more complicated, and indeed impossible on some operating systems (iOS) -- unlike programming language vendors, some chat platform providers are hostile to third party clients (WhatsApp, Discord) - -Despite the downsides, I am interested to see if such an approach could gain traction. LSP has many clients now, of which the original (VS Code) is just one. There are language servers for nearly all popular programming languages as well; so the choices available to software developers wanting useful features has increased enormously. I'd really like to see the same happen in the messaging space. \ No newline at end of file diff --git a/content/posts/2021-12-28-chat-server-protocol.smd b/content/posts/2021-12-28-chat-server-protocol.smd new file mode 100644 index 0000000..4d8e084 --- /dev/null +++ b/content/posts/2021-12-28-chat-server-protocol.smd @@ -0,0 +1,33 @@ +--- +.title = "Chat Server Protocol", +.author = "Martin Ashby", +.date = @date("2021-12-28T22:22:01Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I wrote a previous post about [clojure](/posts/2021-10-06-clojure/) where I expressed an intent to write a slack clone using the language. Like most ideas, this didn't go anywhere, however it did spawn a new idea: Chat Server Protocol. + +There are several different popular messaging platforms, each used by different groups of people I know, for example WhatsApp, Telegram, Signal, Facebook Messenger, Slack & Discord. Having to install each one and learn the particulars of it's user interface can be tiresome. Some of them only cater for certain platforms via their official apps, e.g. WhatsApp is only available for iOS, Android and KaiOS. + +Naturally some people have tried to solve this problem already and provide a universal chat client. Here are some projects I know about and what their approach is: + +- [meetfranz](https://meetfranz.com/) is embedding the web UI of each chat platform into a single electron app. +- [pidgin](https://pidgin.im/) is running a plugin system where contributors can write a shared library to support a new platform. +- [beeper](https://beeper.com) is bridging messaging platforms on the server side and using [matrix](https://matrix.org) as a central system. + +All of these approaches have some drawbacks. For example, franz isn't saving you from learning the web UI of each platform (citation needed, I need to try franz for longer first). Beeper relies on a hosted service running the matrix server and bridges, and you must also trust them to hold credentials to the various platforms. + +I prefer pidgin's approach: a plugin system. The code is split into several pieces: libpurple is the 'core' which handles the basic functions of a messenger app. There are many 'plugins' which link into the core to provide implementations for different platforms. There are several UI programs which then build on libpurple to provide a user interface. Pidgin is one of these, and it provides an interface using GTK+. + +This approach lowers the barrier to entry for integrating new messaging platforms, because the developer does not _also_ have to write the user interface. It also lowers the barrier to entry for writing new user interfaces, since the developer does not also have to write the backend integration to the messaging platform. However, the most significant downside is that plugins are called as shared libraries. This means plugin developers are restricted to C, C++ or other languages that can follow C function calling conventions. Theoretically most languages can do this, however it is often impractical, for example [calling java functions from C](https://nachtimwald.com/2017/06/17/calling-java-from-c/) involves booting up a JVM from your C code. + +A similar problem has recently been solved in the field of IDE's (Integrated Development Environments): Language Server Protocol is a protocol which defines all the 'core' operations of an IDE. Requests are made by a 'client' to a 'server' via IPC (Inter-process communication) mechanisms such as standard streams (stdin/out), TCP or unix sockets or named pipes. + +I propose the same technique could be applied to chat applications: define a 'Chat Server Protocol' which encapsulates all the core operations of a chat app. Clients and servers can then both be written against this protocol enabling far greater interoperability. Since the only requirement for implementing the protocol is some IPC mechanism, which every practical programming langauge supports, then this provides much greater implementation flexibility compared to libpurple. An additional benefit is that crashes in the server implementation can be handled more gracefully by the client, since they are in different processes a crash in the server will not automatically kill the client. + +Some potential problems with this approach: +- multi-processing is more complicated, and indeed impossible on some operating systems (iOS) +- unlike programming language vendors, some chat platform providers are hostile to third party clients (WhatsApp, Discord) + +Despite the downsides, I am interested to see if such an approach could gain traction. LSP has many clients now, of which the original (VS Code) is just one. There are language servers for nearly all popular programming languages as well; so the choices available to software developers wanting useful features has increased enormously. I'd really like to see the same happen in the messaging space. \ No newline at end of file diff --git a/content/posts/2022-02-11-philosophy-software-dev.md b/content/posts/2022-02-11-philosophy-software-dev.md deleted file mode 100644 index 6319350..0000000 --- a/content/posts/2022-02-11-philosophy-software-dev.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -.title = "Book - Philosophy Of Software Design", -.author = "Martin Ashby", -.date = @date("2022-02-11T19:18:07Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -This is my short list of ideas I've taken away from reading [a Philosophy of Software Design](https://www.goodreads.com/en/book/show/39996759-a-philosophy-of-software-design) by John Ousterhout. - -* All the following advice is to be taken in moderation and with consideration for individual circumstance. Taking anything to it's logical extreme usually results in poor outcomes. -* Complexity is the enemy of understanding. -* 'Deep' interfaces are better than 'shallow' ones. Practically this means: keep your interfaces as simple as possible, and contain/handle the complexity in the implementation. Prime example was the linux/unix file system API. -* Spend time on design. Consider alternatives, discuss them with colleagues. -* Choose accurate, consistent names. -* If a reviewer doesn't understand your code, it is not clear enough. Listen to them, and make it clearer somehow. - -I agreed very strongly with all of the above. The idea of 'deep' interfaces expresses something I have been previously unable to express succinctly, and I will try to apply this in my own code and reviews. I also think I will try this tip: - -* Write comments/documentation _first_, i.e. while you are designing. This helps to find high-level problems in the design, before you have already spent time coding it. - -I disagreed on some minor points: - -* in section 8.2, it is advised to avoid configuration parameters. They are an indication that your system isn't handling complexity, and shifting responsibility to the operators of the system. In general, I think it's much better to: 1. make everything configurable (within reason) and 2. provide sensible defaults for the most common cases. The author recommends auto-tuning parameters, however I think this is overkill in most cases, and also takes away control from the operator or user of the software. -* In section 18.2, it is advised to always use the same type for variable declaration and allocation. The author gives the example of a local variable declared as a `java.util.List`, but instanciated as an `ArrayList`, and cites differing performance characteristics as a potential hazard for users of the variable. I think this example is poor; it sounds like premature optimization, and it risks users of the variable using implementation-specific methods and making it more difficult to e.g. change the type of the list later. -* In section 19.3 the author asserts that unit tests have the greatest coverage, and are therefore the best tool for uncovering bugs. I think this is something where YMMV. It really depends on the quality of the unit tests, and the most typical sources of bugs in your application. I think (although I can't prove) that _most_ bugs are found in the interactions of multiple modules, and unit tests will not catch those as they are (by definition) only testing one module. - -I would recommend this book to pretty much all software developers at any level. I think everyone in software could find something to take away and use in their work, to the benefit of their projects (and colleagues!). diff --git a/content/posts/2022-02-11-philosophy-software-dev.smd b/content/posts/2022-02-11-philosophy-software-dev.smd new file mode 100644 index 0000000..6319350 --- /dev/null +++ b/content/posts/2022-02-11-philosophy-software-dev.smd @@ -0,0 +1,28 @@ +--- +.title = "Book - Philosophy Of Software Design", +.author = "Martin Ashby", +.date = @date("2022-02-11T19:18:07Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +This is my short list of ideas I've taken away from reading [a Philosophy of Software Design](https://www.goodreads.com/en/book/show/39996759-a-philosophy-of-software-design) by John Ousterhout. + +* All the following advice is to be taken in moderation and with consideration for individual circumstance. Taking anything to it's logical extreme usually results in poor outcomes. +* Complexity is the enemy of understanding. +* 'Deep' interfaces are better than 'shallow' ones. Practically this means: keep your interfaces as simple as possible, and contain/handle the complexity in the implementation. Prime example was the linux/unix file system API. +* Spend time on design. Consider alternatives, discuss them with colleagues. +* Choose accurate, consistent names. +* If a reviewer doesn't understand your code, it is not clear enough. Listen to them, and make it clearer somehow. + +I agreed very strongly with all of the above. The idea of 'deep' interfaces expresses something I have been previously unable to express succinctly, and I will try to apply this in my own code and reviews. I also think I will try this tip: + +* Write comments/documentation _first_, i.e. while you are designing. This helps to find high-level problems in the design, before you have already spent time coding it. + +I disagreed on some minor points: + +* in section 8.2, it is advised to avoid configuration parameters. They are an indication that your system isn't handling complexity, and shifting responsibility to the operators of the system. In general, I think it's much better to: 1. make everything configurable (within reason) and 2. provide sensible defaults for the most common cases. The author recommends auto-tuning parameters, however I think this is overkill in most cases, and also takes away control from the operator or user of the software. +* In section 18.2, it is advised to always use the same type for variable declaration and allocation. The author gives the example of a local variable declared as a `java.util.List`, but instanciated as an `ArrayList`, and cites differing performance characteristics as a potential hazard for users of the variable. I think this example is poor; it sounds like premature optimization, and it risks users of the variable using implementation-specific methods and making it more difficult to e.g. change the type of the list later. +* In section 19.3 the author asserts that unit tests have the greatest coverage, and are therefore the best tool for uncovering bugs. I think this is something where YMMV. It really depends on the quality of the unit tests, and the most typical sources of bugs in your application. I think (although I can't prove) that _most_ bugs are found in the interactions of multiple modules, and unit tests will not catch those as they are (by definition) only testing one module. + +I would recommend this book to pretty much all software developers at any level. I think everyone in software could find something to take away and use in their work, to the benefit of their projects (and colleagues!). diff --git a/content/posts/2022-02-23-wordle.md b/content/posts/2022-02-23-wordle.md deleted file mode 100644 index d2d576a..0000000 --- a/content/posts/2022-02-23-wordle.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -.title = "Wordle", -.author = "Martin Ashby", -.date = @date("2022-02-23T13:41:22Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I really enjoyed playing [wordle](https://www.powerlanguage.co.uk/wordle/) recently, and I really appreciated how simple and fun the game is. I enjoyed comparing my scores with my friends and family; it's also fun to see people learning new words! - -From a technical point of view, wordle is also a really neat and simple game. Everything is client-side, there's no server component, so it can be played offline. Even the sharing feature, unicode squares to show how accurate your guesses were without reavealing the word, is so simple and yet so effective. - -The only thing I missed was a leaderboard to see who has that competitive edge :) - -So I [wrote my own](https://wordle.mfashby.net) and I also chose to [write it C](https://github.com/MFAshby/mordle)(and HTML, SQL, and a tiny bit of javascript), to see how different it would be to my usual choices (java or golang). - -Overall I'm pleased with the result; it uses very little resource and it wasn't as difficult as I had imagined to use a 'lower level' language like C, although there is a fairly significant amount of code for such a simple game, and it's nowhere near as polished an experience as the original. - diff --git a/content/posts/2022-02-23-wordle.smd b/content/posts/2022-02-23-wordle.smd new file mode 100644 index 0000000..d2d576a --- /dev/null +++ b/content/posts/2022-02-23-wordle.smd @@ -0,0 +1,18 @@ +--- +.title = "Wordle", +.author = "Martin Ashby", +.date = @date("2022-02-23T13:41:22Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I really enjoyed playing [wordle](https://www.powerlanguage.co.uk/wordle/) recently, and I really appreciated how simple and fun the game is. I enjoyed comparing my scores with my friends and family; it's also fun to see people learning new words! + +From a technical point of view, wordle is also a really neat and simple game. Everything is client-side, there's no server component, so it can be played offline. Even the sharing feature, unicode squares to show how accurate your guesses were without reavealing the word, is so simple and yet so effective. + +The only thing I missed was a leaderboard to see who has that competitive edge :) + +So I [wrote my own](https://wordle.mfashby.net) and I also chose to [write it C](https://github.com/MFAshby/mordle)(and HTML, SQL, and a tiny bit of javascript), to see how different it would be to my usual choices (java or golang). + +Overall I'm pleased with the result; it uses very little resource and it wasn't as difficult as I had imagined to use a 'lower level' language like C, although there is a fairly significant amount of code for such a simple game, and it's nowhere near as polished an experience as the original. + diff --git a/content/posts/2022-03-19-wildcard.md b/content/posts/2022-03-19-wildcard.md deleted file mode 100644 index 05c780f..0000000 --- a/content/posts/2022-03-19-wildcard.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -.title = "Wildcard", -.author = "Martin Ashby", -.date = @date("2022-03-19T13:17:26Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I've switched to using a wildcard certificate for everything I host on `*.mfashby.net`. - -It keeps my nginx configuration a bit less repetitive. It also allows internal services (i.e. not accessible to the internet) be secured with TLS more conveniently, and without those nasty browser warnings about self-signed certificates. - diff --git a/content/posts/2022-03-19-wildcard.smd b/content/posts/2022-03-19-wildcard.smd new file mode 100644 index 0000000..05c780f --- /dev/null +++ b/content/posts/2022-03-19-wildcard.smd @@ -0,0 +1,12 @@ +--- +.title = "Wildcard", +.author = "Martin Ashby", +.date = @date("2022-03-19T13:17:26Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I've switched to using a wildcard certificate for everything I host on `*.mfashby.net`. + +It keeps my nginx configuration a bit less repetitive. It also allows internal services (i.e. not accessible to the internet) be secured with TLS more conveniently, and without those nasty browser warnings about self-signed certificates. + diff --git a/content/posts/2022-03-27-fossil.md b/content/posts/2022-03-27-fossil.md deleted file mode 100644 index 135c419..0000000 --- a/content/posts/2022-03-27-fossil.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -.title = "Fossil", -.author = "Martin Ashby", -.date = @date("2022-03-27T11:28:31+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I have switched to using [fossil SCM](https://fossil-scm.org) for managing the source code of this website. I am attracted to the idea of having a decentralized store not only for code but also for tickets, wiki, forums / chat, etc etc. Basically everything github provides, but capable of offline working. - -Fossil is quite different to git, so I expect some learning curve. Starting with my own personal site is easy enough. I also have fossil running as a server on code.mfashby.net, and I might try to convert the old github repository into a mirror of the fossil. diff --git a/content/posts/2022-03-27-fossil.smd b/content/posts/2022-03-27-fossil.smd new file mode 100644 index 0000000..135c419 --- /dev/null +++ b/content/posts/2022-03-27-fossil.smd @@ -0,0 +1,11 @@ +--- +.title = "Fossil", +.author = "Martin Ashby", +.date = @date("2022-03-27T11:28:31+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I have switched to using [fossil SCM](https://fossil-scm.org) for managing the source code of this website. I am attracted to the idea of having a decentralized store not only for code but also for tickets, wiki, forums / chat, etc etc. Basically everything github provides, but capable of offline working. + +Fossil is quite different to git, so I expect some learning curve. Starting with my own personal site is easy enough. I also have fossil running as a server on code.mfashby.net, and I might try to convert the old github repository into a mirror of the fossil. diff --git a/content/posts/2022-04-30-longboard-3.md b/content/posts/2022-04-30-longboard-3.md deleted file mode 100644 index 0cba41e..0000000 --- a/content/posts/2022-04-30-longboard-3.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -.title = "Longboard 3", -.author = "Martin Ashby", -.date = @date("2022-04-30T19:49:39+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- -Since my [last post](/2021-11-09-longboard-2/) on longboarding, I've become a lot more comfortable with push-up and coleman slides, and now I aim to learn [toeside pendulum slide](https://youtu.be/a5B_XaubQNE). I have had limited success so far, and one bad high-side attempting it (fall down-hill direction, as opposed to low-side falling in the uphill direction). Luckily my helmet did it's job, I'll be trying again in the future. - -I have also bought a second board, an [original apex diamond drop 37"](https://originalskateboards.com/longboards/apex-37-diamonddrop-longboard/), obtained second hand from facebook marketplace. It differs from the Lush Freebyrd in a couple of ways: -* It has usable kick-tails, which opens up some freestyle skating opportunities (manuals, pivots, ollies, etc) -* As a result, it's a drop-deck rather than a drop-through, to retain the low & stable ride height and remain strong enough for freestyle. - -[Here](https://youtu.be/oVB5Karx-90) is a review from Axel Serrat (weirdly, NSFW). It should be noted this guy can probably skate a plank of wood with rocks on the bottom better than I can skate this nice board. - -This particular board has caliber II (reverse king pin) trucks. I've swapped the 90a bushings for very soft 85/87a since I don't weigh very much. This is really carvy and I quite like how it rides as a result. I've also swapped my powell-peralta snakes to this board and returned the cultrons to my freebyrd. I really didn't like the [rad glides](https://tgmskateboards.com/rad-wheels-glide-70mm-82a/) which the previous owner had fitted, they seemed very hard for my terrain. I might give them another go as they should be very slidey, but for now they are shelved. - -Much more importantly, I've found a fellow longboarder to skate with, and a couple of new spots nearby. Videos to follow! - - -![Apex Diamond Drop Top](apex_1.jpg) -![Apex Diamond Drop Bottom](apex_2.jpg) - diff --git a/content/posts/2022-04-30-longboard-3.smd b/content/posts/2022-04-30-longboard-3.smd new file mode 100644 index 0000000..aa11b2b --- /dev/null +++ b/content/posts/2022-04-30-longboard-3.smd @@ -0,0 +1,23 @@ +--- +.title = "Longboard 3", +.author = "Martin Ashby", +.date = @date("2022-04-30T19:49:39+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- +Since my [last post](/posts/2021-11-09-longboard-2) on longboarding, I've become a lot more comfortable with push-up and coleman slides, and now I aim to learn [toeside pendulum slide](https://youtu.be/a5B_XaubQNE). I have had limited success so far, and one bad high-side attempting it (fall down-hill direction, as opposed to low-side falling in the uphill direction). Luckily my helmet did it's job, I'll be trying again in the future. + +I have also bought a second board, an [original apex diamond drop 37"](https://originalskateboards.com/longboards/apex-37-diamonddrop-longboard/), obtained second hand from facebook marketplace. It differs from the Lush Freebyrd in a couple of ways: +* It has usable kick-tails, which opens up some freestyle skating opportunities (manuals, pivots, ollies, etc) +* As a result, it's a drop-deck rather than a drop-through, to retain the low & stable ride height and remain strong enough for freestyle. + +[Here](https://youtu.be/oVB5Karx-90) is a review from Axel Serrat (weirdly, NSFW). It should be noted this guy can probably skate a plank of wood with rocks on the bottom better than I can skate this nice board. + +This particular board has caliber II (reverse king pin) trucks. I've swapped the 90a bushings for very soft 85/87a since I don't weigh very much. This is really carvy and I quite like how it rides as a result. I've also swapped my powell-peralta snakes to this board and returned the cultrons to my freebyrd. I really didn't like the [rad glides](https://tgmskateboards.com/rad-wheels-glide-70mm-82a/) which the previous owner had fitted, they seemed very hard for my terrain. I might give them another go as they should be very slidey, but for now they are shelved. + +Much more importantly, I've found a fellow longboarder to skate with, and a couple of new spots nearby. Videos to follow! + + +![Apex Diamond Drop Top](apex_1.jpg) +![Apex Diamond Drop Bottom](apex_2.jpg) + diff --git a/content/posts/2022-05-07-stolen-focus.md b/content/posts/2022-05-07-stolen-focus.md deleted file mode 100644 index 1e74ace..0000000 --- a/content/posts/2022-05-07-stolen-focus.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -.title = "Book - Stolen Focus", -.author = "Martin Ashby", -.date = @date("2022-05-07T15:18:58+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I've recently finished reading [Stolen Focus](stolenfocusbook.com/) by Johann Hari. - -In it, the author presents an argument that online social media (i.e. facebook, instagram, etc) is currently harmful, and this is because of misaligned incentives. The companies producing this software are funded by advertisers, whose adverts are more effective if they spend more time in front of user's eyes. This results in platforms optimizing for 'engagement' among users; i.e. more time spent on the site. Human negative reactions are stronger, and causing these emotions keeps users on the site for longer than positive ones. Therefore to increase screen time, platforms end up presenting stories that enrage the user. This has a variety of negative impacts including; polarizing the user's beliefs, adding stress and alienating other people. - -I hadn't come across this particular argument before, it seems fairly compelling. It rests on a couple of premises, for which Johann provides some evidence; -* Social media companies are indeed optimizing for 'screen time' engagement in order to maximize profit. -* Optimizing for increased screen time does indeed result in the negative effects (wasted time, stress, polarization) - -Johann suggests banning this business model. Only when the companies' incentives are aligned with the users of their product can they instead optimize their product in a way that improves the users' quality of life. Two suggestions for changing the business model are proposed; 1. charging users for the product, 2. acquisition by government. Neither suggestion is without it's own significant problems. - -The book also touches on many other subjects, in fact the author lists around a dozen reasons why our attention span today is more limited than in the past. These include increased air pollution and decreased childhood freedom for example. He also makes the critical point that a failing attention span is not only a personal problem; while there is personal variation, the wider environment has a huge impact. This means that personal efforts to improve the situation are more likely to be stymied. This is similar to some other problems like obesity; where e.g. the environment is full of cheap, sugary, processed, high-fat foods, and yet people feel solely responsible when they gain excess weight, or fail to lose it. - -Personally, the book has made me more conscious of my personal habits regarding my phone & social media usage. It has also made me more conscious of my work as a software enginneer; that misaligned incentives can have very negative consequences for users of your software. You should find a business model that somehow translates increased quality of life for users into profit. It also highlighted the importance of collective action for improving society; we should remember that our high quality of life right now is a direct result of many collective actions in the past. diff --git a/content/posts/2022-05-07-stolen-focus.smd b/content/posts/2022-05-07-stolen-focus.smd new file mode 100644 index 0000000..d1141dd --- /dev/null +++ b/content/posts/2022-05-07-stolen-focus.smd @@ -0,0 +1,21 @@ +--- +.title = "Book - Stolen Focus", +.author = "Martin Ashby", +.date = @date("2022-05-07T15:18:58+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I've recently finished reading [Stolen Focus](https://stolenfocusbook.com/) by Johann Hari. + +In it, the author presents an argument that online social media (i.e. facebook, instagram, etc) is currently harmful, and this is because of misaligned incentives. The companies producing this software are funded by advertisers, whose adverts are more effective if they spend more time in front of user's eyes. This results in platforms optimizing for 'engagement' among users; i.e. more time spent on the site. Human negative reactions are stronger, and causing these emotions keeps users on the site for longer than positive ones. Therefore to increase screen time, platforms end up presenting stories that enrage the user. This has a variety of negative impacts including; polarizing the user's beliefs, adding stress and alienating other people. + +I hadn't come across this particular argument before, it seems fairly compelling. It rests on a couple of premises, for which Johann provides some evidence; +* Social media companies are indeed optimizing for 'screen time' engagement in order to maximize profit. +* Optimizing for increased screen time does indeed result in the negative effects (wasted time, stress, polarization) + +Johann suggests banning this business model. Only when the companies' incentives are aligned with the users of their product can they instead optimize their product in a way that improves the users' quality of life. Two suggestions for changing the business model are proposed; 1. charging users for the product, 2. acquisition by government. Neither suggestion is without it's own significant problems. + +The book also touches on many other subjects, in fact the author lists around a dozen reasons why our attention span today is more limited than in the past. These include increased air pollution and decreased childhood freedom for example. He also makes the critical point that a failing attention span is not only a personal problem; while there is personal variation, the wider environment has a huge impact. This means that personal efforts to improve the situation are more likely to be stymied. This is similar to some other problems like obesity; where e.g. the environment is full of cheap, sugary, processed, high-fat foods, and yet people feel solely responsible when they gain excess weight, or fail to lose it. + +Personally, the book has made me more conscious of my personal habits regarding my phone & social media usage. It has also made me more conscious of my work as a software enginneer; that misaligned incentives can have very negative consequences for users of your software. You should find a business model that somehow translates increased quality of life for users into profit. It also highlighted the importance of collective action for improving society; we should remember that our high quality of life right now is a direct result of many collective actions in the past. diff --git a/content/posts/2022-06-09-rustlings.md b/content/posts/2022-06-09-rustlings.md deleted file mode 100644 index 332c87a..0000000 --- a/content/posts/2022-06-09-rustlings.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -.title = "Rustlings", -.author = "Martin Ashby", -.date = @date("2022-06-09T21:58:40+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I recently completed the [rustlings](https://github.com/rust-lang/rustlings/) introduction to learning the [Rust](https://www.rust-lang.org/) programming language. - -I have previously tried reading the [book](https://doc.rust-lang.org/book/), but I learn much better by doing and experimenting than reading. I found the rustlings course to by very accessible. It's probably a little easy for an experienced software developer, and it skips some of the gnarlier topics like lifetime parameters. - -I hope to make a couple of little projects in Rust just to get to know the language. - diff --git a/content/posts/2022-06-09-rustlings.smd b/content/posts/2022-06-09-rustlings.smd new file mode 100644 index 0000000..332c87a --- /dev/null +++ b/content/posts/2022-06-09-rustlings.smd @@ -0,0 +1,14 @@ +--- +.title = "Rustlings", +.author = "Martin Ashby", +.date = @date("2022-06-09T21:58:40+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I recently completed the [rustlings](https://github.com/rust-lang/rustlings/) introduction to learning the [Rust](https://www.rust-lang.org/) programming language. + +I have previously tried reading the [book](https://doc.rust-lang.org/book/), but I learn much better by doing and experimenting than reading. I found the rustlings course to by very accessible. It's probably a little easy for an experienced software developer, and it skips some of the gnarlier topics like lifetime parameters. + +I hope to make a couple of little projects in Rust just to get to know the language. + diff --git a/content/posts/2022-07-09-longboard-4.md b/content/posts/2022-07-09-longboard-4.md deleted file mode 100644 index b87131e..0000000 --- a/content/posts/2022-07-09-longboard-4.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -.title = "Longboard 4", -.author = "Martin Ashby", -.date = @date("2022-07-09T22:00:07+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -Since the [last](/posts/2022-04-30-longboard-3/) post on longboarding, I've started skating at the local park with a friend. Park skating is pretty different to downhill & freeride! It's a lot of fun. It challenges you to think about how you're going to navigate the park (what line you'll take), and pushes the boundaries of what you are capable of. It also looks awesome :) - -There's lots of guidance on park skating, [this video](https://www.youtube.com/watch?v=zTVb4bmoiw0) was a brief but useful introduction to park etiquette, pumps and kick turns. - -I hope to put together a short video of skating footage from over the summer later in the year. - diff --git a/content/posts/2022-07-09-longboard-4.smd b/content/posts/2022-07-09-longboard-4.smd new file mode 100644 index 0000000..b87131e --- /dev/null +++ b/content/posts/2022-07-09-longboard-4.smd @@ -0,0 +1,14 @@ +--- +.title = "Longboard 4", +.author = "Martin Ashby", +.date = @date("2022-07-09T22:00:07+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +Since the [last](/posts/2022-04-30-longboard-3/) post on longboarding, I've started skating at the local park with a friend. Park skating is pretty different to downhill & freeride! It's a lot of fun. It challenges you to think about how you're going to navigate the park (what line you'll take), and pushes the boundaries of what you are capable of. It also looks awesome :) + +There's lots of guidance on park skating, [this video](https://www.youtube.com/watch?v=zTVb4bmoiw0) was a brief but useful introduction to park etiquette, pumps and kick turns. + +I hope to put together a short video of skating footage from over the summer later in the year. + diff --git a/content/posts/2022-07-30-fossil2.md b/content/posts/2022-07-30-fossil2.md deleted file mode 100644 index 0df1211..0000000 --- a/content/posts/2022-07-30-fossil2.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -.title = "Fossil 2", -.author = "Martin Ashby", -.date = @date("2022-07-30T22:57:38+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I tidied up [my github](https://github.com/MFAshby) and archived a bunch of old repositories. The few that I have kept, I have moved to my [self-hosted fossil](https://code.mfashby.net), and I have enabled a few useful options there like [login-groups](https://fossil-scm.org/home/doc/trunk/www/caps/login-groups.md) and correctly setting base URL and individual repository paths within fossil. - -It transpired I didn't have many (any?) useful personal repositories. I have kept the repo for this site, a couple of old (and super old) hobby projects, my dotfiles, and exercises from [the C programming language](https://en.wikipedia.org/wiki/The_C_Programming_Language) which I am currently working through very slowly. diff --git a/content/posts/2022-07-30-fossil2.smd b/content/posts/2022-07-30-fossil2.smd new file mode 100644 index 0000000..0df1211 --- /dev/null +++ b/content/posts/2022-07-30-fossil2.smd @@ -0,0 +1,11 @@ +--- +.title = "Fossil 2", +.author = "Martin Ashby", +.date = @date("2022-07-30T22:57:38+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I tidied up [my github](https://github.com/MFAshby) and archived a bunch of old repositories. The few that I have kept, I have moved to my [self-hosted fossil](https://code.mfashby.net), and I have enabled a few useful options there like [login-groups](https://fossil-scm.org/home/doc/trunk/www/caps/login-groups.md) and correctly setting base URL and individual repository paths within fossil. + +It transpired I didn't have many (any?) useful personal repositories. I have kept the repo for this site, a couple of old (and super old) hobby projects, my dotfiles, and exercises from [the C programming language](https://en.wikipedia.org/wiki/The_C_Programming_Language) which I am currently working through very slowly. diff --git a/content/posts/2022-09-09-serverless.md b/content/posts/2022-09-09-serverless.md deleted file mode 100644 index 2ae16cf..0000000 --- a/content/posts/2022-09-09-serverless.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -.title = "Serverless", -.author = "Martin Ashby", -.date = @date("2022-09-09T21:48:19+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -At work, our main product is a web application. Its primary function is receiving health data from hospital systems (and GP systems, and anyone else that has health data) and making it available to patients. I've been heavily involved in the infrastructure side of things; including migration to public cloud infrastructure. - -Our infrastructure is complicated. We use SQL databases, Redis, Cloud storage buckets, and messaging systems as stateful components. We use kubernetes to run our application(s). Even though all of these are managed to some extent by the hosting provider, a lot of the detail is still left up to us; for example provisioning groups and users, scheduling upgrades, handling deprecation of APIs. Also our customers frequently ask things like 'where is your data hosted' and 'which standards for data security do you conform to'. These are reasonable questions. - -It gets even more complicated when you have to also consider CI pipelines, and security at every step of the supply chain from developer machine, to production data, to support staff, and even _more_ complicated when you start trying to build out business intelligence. - -I've often found myself asking if things could be simpler. One way things could be simpler is [just use one big server](https://specbranch.com/posts/one-big-server/). This is really alluring, right up to the point where either your one big server explodes, or can't get any bigger. It can also mask scaling problems in your code, for example the classic N+1 query problem isn't really a problem if your application and database are on the same server, but it is almost certainly a problem the moment that any latency is introduced by e.g. a network hop. One big server is probably still fine in a lot of cases though. - -Another way things could be simpler is to let platforms handle more of the infrastructure and scaling concern for you. I've been experimenting with [Darklang](https://darklang.com/) which aims to provide _everything_ you need to write web applications (like ours), all hosted and managed right from the code editor to 'production', so you can spend nearly zero time thinking about, and working on, infrastructure. There are some pretty big tradeoffs at the moment, for example: the platform revolves around an entirely new language, so there are very few libraries. There is no separation of 'staging' and 'production', code in a canvas is live immediately, which would require a pretty significant change in approach for code review and testing. Code is not portable, there is only one darklang environment right now, so if that goes away for any reason, you have to rewrite. - -Infrastructure for a company that doesn't sell infrastructure is purely a 'cost centre' i.e. something that's necessary for the company to function, but isn't a direct money-maker. We're not selling infrastructure, we're selling a product built on that infrastructure. I hope that something like darklang becomes mature and useful in future; and software developers can cut out a big chunk of time spent worrying about infrastructure. - -Maybe I could even spend that time skating instead. diff --git a/content/posts/2022-09-09-serverless.smd b/content/posts/2022-09-09-serverless.smd new file mode 100644 index 0000000..2ae16cf --- /dev/null +++ b/content/posts/2022-09-09-serverless.smd @@ -0,0 +1,21 @@ +--- +.title = "Serverless", +.author = "Martin Ashby", +.date = @date("2022-09-09T21:48:19+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +At work, our main product is a web application. Its primary function is receiving health data from hospital systems (and GP systems, and anyone else that has health data) and making it available to patients. I've been heavily involved in the infrastructure side of things; including migration to public cloud infrastructure. + +Our infrastructure is complicated. We use SQL databases, Redis, Cloud storage buckets, and messaging systems as stateful components. We use kubernetes to run our application(s). Even though all of these are managed to some extent by the hosting provider, a lot of the detail is still left up to us; for example provisioning groups and users, scheduling upgrades, handling deprecation of APIs. Also our customers frequently ask things like 'where is your data hosted' and 'which standards for data security do you conform to'. These are reasonable questions. + +It gets even more complicated when you have to also consider CI pipelines, and security at every step of the supply chain from developer machine, to production data, to support staff, and even _more_ complicated when you start trying to build out business intelligence. + +I've often found myself asking if things could be simpler. One way things could be simpler is [just use one big server](https://specbranch.com/posts/one-big-server/). This is really alluring, right up to the point where either your one big server explodes, or can't get any bigger. It can also mask scaling problems in your code, for example the classic N+1 query problem isn't really a problem if your application and database are on the same server, but it is almost certainly a problem the moment that any latency is introduced by e.g. a network hop. One big server is probably still fine in a lot of cases though. + +Another way things could be simpler is to let platforms handle more of the infrastructure and scaling concern for you. I've been experimenting with [Darklang](https://darklang.com/) which aims to provide _everything_ you need to write web applications (like ours), all hosted and managed right from the code editor to 'production', so you can spend nearly zero time thinking about, and working on, infrastructure. There are some pretty big tradeoffs at the moment, for example: the platform revolves around an entirely new language, so there are very few libraries. There is no separation of 'staging' and 'production', code in a canvas is live immediately, which would require a pretty significant change in approach for code review and testing. Code is not portable, there is only one darklang environment right now, so if that goes away for any reason, you have to rewrite. + +Infrastructure for a company that doesn't sell infrastructure is purely a 'cost centre' i.e. something that's necessary for the company to function, but isn't a direct money-maker. We're not selling infrastructure, we're selling a product built on that infrastructure. I hope that something like darklang becomes mature and useful in future; and software developers can cut out a big chunk of time spent worrying about infrastructure. + +Maybe I could even spend that time skating instead. diff --git a/content/posts/2022-09-25-back-to-git.md b/content/posts/2022-09-25-back-to-git.md deleted file mode 100644 index 0daedc3..0000000 --- a/content/posts/2022-09-25-back-to-git.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -.title = "Back to Git", -.author = "Martin Ashby", -.date = @date("2022-09-25T21:09:31+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I moved back to git from fossil SCM, after [previously](posts/2022-03-27-fossil/) migrating the other way. - -I use git for work and so couldn't forget how to use git and go all-in on fossil, and remembering two sets of commands proved somewhat painful and I wasn't seeing the benefit of built-in issue tracking or anything like that. Now I run [gitea](https://gitea.io/) git server instead. - -Weirdly I don't have too much trouble remembering two programming languages, but I think that's slightly different somehow. diff --git a/content/posts/2022-09-25-back-to-git.smd b/content/posts/2022-09-25-back-to-git.smd new file mode 100644 index 0000000..dfebb2b --- /dev/null +++ b/content/posts/2022-09-25-back-to-git.smd @@ -0,0 +1,13 @@ +--- +.title = "Back to Git", +.author = "Martin Ashby", +.date = @date("2022-09-25T21:09:31+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I moved back to git from fossil SCM, after [previously](/posts/2022-03-27-fossil/) migrating the other way. + +I use git for work and so couldn't forget how to use git and go all-in on fossil, and remembering two sets of commands proved somewhat painful and I wasn't seeing the benefit of built-in issue tracking or anything like that. Now I run [gitea](https://gitea.io/) git server instead. + +Weirdly I don't have too much trouble remembering two programming languages, but I think that's slightly different somehow. diff --git a/content/posts/2022-10-07-blocky.md b/content/posts/2022-10-07-blocky.md deleted file mode 100644 index cfe87b7..0000000 --- a/content/posts/2022-10-07-blocky.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -.title = "Blocky", -.author = "Martin Ashby", -.date = @date("2022-10-07T20:24:03+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I recently revisited the idea of installing [pi-hole](https://pi-hole.net/) in my local network to help remove ads from miscellaneous devices on my network. However, my raspberry pi already runs a lot of stuff including this blog, and runs on an unsupported-by-pi-hole OS (manjaro linux). - -I found another tool [blocky](https://0xerr0r.github.io/blocky/) which is a DNS server with a lot of the same features as pi-hole. It has a reasonably simple configuration file and uses sane defaults for things I don't want to configure. It's distributed as a single binary, and it was trivially available in the arch user repository. - -One thing this doesn't do is act as a DHCP server. For now I'm accessing the DNS server over [tailscale](https://tailscale.com), following [this article](https://tailscale.com/kb/1114/pi-hole/) explaining how to set a custom DNS server for your tailnet. I'll check how well this works for some time on my devices using tailscale, then later investigate how to configure my router to supply my DNS server instead of it's own to connecting devices so any other network devices get the same filters. diff --git a/content/posts/2022-10-07-blocky.smd b/content/posts/2022-10-07-blocky.smd new file mode 100644 index 0000000..cfe87b7 --- /dev/null +++ b/content/posts/2022-10-07-blocky.smd @@ -0,0 +1,13 @@ +--- +.title = "Blocky", +.author = "Martin Ashby", +.date = @date("2022-10-07T20:24:03+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I recently revisited the idea of installing [pi-hole](https://pi-hole.net/) in my local network to help remove ads from miscellaneous devices on my network. However, my raspberry pi already runs a lot of stuff including this blog, and runs on an unsupported-by-pi-hole OS (manjaro linux). + +I found another tool [blocky](https://0xerr0r.github.io/blocky/) which is a DNS server with a lot of the same features as pi-hole. It has a reasonably simple configuration file and uses sane defaults for things I don't want to configure. It's distributed as a single binary, and it was trivially available in the arch user repository. + +One thing this doesn't do is act as a DHCP server. For now I'm accessing the DNS server over [tailscale](https://tailscale.com), following [this article](https://tailscale.com/kb/1114/pi-hole/) explaining how to set a custom DNS server for your tailnet. I'll check how well this works for some time on my devices using tailscale, then later investigate how to configure my router to supply my DNS server instead of it's own to connecting devices so any other network devices get the same filters. diff --git a/content/posts/2022-10-09-quine.md b/content/posts/2022-10-09-quine.md deleted file mode 100644 index 827e86c..0000000 --- a/content/posts/2022-10-09-quine.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -.title = "Quine", -.author = "Martin Ashby", -.date = @date("2022-10-09T13:11:52+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -A [quine](https://en.wikipedia.org/wiki/Quine_%28computing%29) is a program that takes no input, and it's output is it's own source code. A quine-relay is a program that outputs the source code for another program, and when that next program is run it outputs the source code of the first program. I recently saw [this quine relay](https://github.com/mame/quine-relay) program which was super impressive as it goes through 128 languages like this! - -Having recently learned some [Rust](https://www.rust-lang.org/), I thought I'd write a simple [quine in rust](https://code.mfashby.net/martin/rust-quine). It wasn't actually as difficult as I imagined, this took about 25 minutes. The rust standard library has a really convenient function `escape_default` which made it pretty easy! - diff --git a/content/posts/2022-10-09-quine.smd b/content/posts/2022-10-09-quine.smd new file mode 100644 index 0000000..827e86c --- /dev/null +++ b/content/posts/2022-10-09-quine.smd @@ -0,0 +1,12 @@ +--- +.title = "Quine", +.author = "Martin Ashby", +.date = @date("2022-10-09T13:11:52+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +A [quine](https://en.wikipedia.org/wiki/Quine_%28computing%29) is a program that takes no input, and it's output is it's own source code. A quine-relay is a program that outputs the source code for another program, and when that next program is run it outputs the source code of the first program. I recently saw [this quine relay](https://github.com/mame/quine-relay) program which was super impressive as it goes through 128 languages like this! + +Having recently learned some [Rust](https://www.rust-lang.org/), I thought I'd write a simple [quine in rust](https://code.mfashby.net/martin/rust-quine). It wasn't actually as difficult as I imagined, this took about 25 minutes. The rust standard library has a really convenient function `escape_default` which made it pretty easy! + diff --git a/content/posts/2022-10-09-skateboard-1.md b/content/posts/2022-10-09-skateboard-1.md deleted file mode 100644 index aa5026d..0000000 --- a/content/posts/2022-10-09-skateboard-1.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -.title = "Skateboard 1", -.author = "Martin Ashby", -.date = @date("2022-10-09T13:21:00+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -Following my [previous post](posts/2022-07-09-longboard-4/) on longboarding, I took a few more trips to the skate park. I eventually decided to buy a regular (or 'popsicle') board as they really open up a lot more of the park, and tricks. - -I bought second hand from a local skater, and I'm quite pleased that I got a board in good condition with nice trucks. However, I'm used to a longboard and I really didn't like the typical skateboard wheels (52mm, 82a hardness) as I found them noisy and slow. I added some risers and fitted 60mm, 75a OJ wheels from a local skate shop. These are really great for cruising. They are not quite so great for tricks, however the difference to me isn't so noticeable since I'm used to large longboard wheels. - -I went through several sets of bushings until finally settling on [bones hardcore medium](https://bones.com/bones-wheels-bushing-medium-white-pack). I tried independent 'soft' and 'super-soft', but the 'soft' ones I found ironically hard, and super-soft felt 'mushy' and didn't return to centre very well. I much prefer the springy-ness of the bones bushings, and the medium hardness lets me avoid wheel-bite while still being easy enough to turn and carve. - -Finally; I bought a skate-tool. Previously I'd been carrying a socket-wrench around in my bag, and it wasn't super convenient. The skate tool fits in my pocket so I can pack lighter :) - -![Skateboard](skateboard.jpg) - - \ No newline at end of file diff --git a/content/posts/2022-10-09-skateboard-1.smd b/content/posts/2022-10-09-skateboard-1.smd new file mode 100644 index 0000000..f7bae1e --- /dev/null +++ b/content/posts/2022-10-09-skateboard-1.smd @@ -0,0 +1,21 @@ +--- +.title = "Skateboard 1", +.author = "Martin Ashby", +.date = @date("2022-10-09T13:21:00+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +Following my [previous post](/posts/2022-07-09-longboard-4/) on longboarding, I took a few more trips to the skate park. I eventually decided to buy a regular (or 'popsicle') board as they really open up a lot more of the park, and tricks. + +I bought second hand from a local skater, and I'm quite pleased that I got a board in good condition with nice trucks. However, I'm used to a longboard and I really didn't like the typical skateboard wheels (52mm, 82a hardness) as I found them noisy and slow. I added some risers and fitted 60mm, 75a OJ wheels from a local skate shop. These are really great for cruising. They are not quite so great for tricks, however the difference to me isn't so noticeable since I'm used to large longboard wheels. + +I went through several sets of bushings until finally settling on [bones hardcore medium](https://bones.com/bones-wheels-bushing-medium-white-pack). I tried independent 'soft' and 'super-soft', but the 'soft' ones I found ironically hard, and super-soft felt 'mushy' and didn't return to centre very well. I much prefer the springy-ness of the bones bushings, and the medium hardness lets me avoid wheel-bite while still being easy enough to turn and carve. + +Finally; I bought a skate-tool. Previously I'd been carrying a socket-wrench around in my bag, and it wasn't super convenient. The skate tool fits in my pocket so I can pack lighter :) + +![Skateboard](skateboard.jpg) + +```=html + +``` \ No newline at end of file diff --git a/content/posts/2022-10-14-blogsite.md b/content/posts/2022-10-14-blogsite.md deleted file mode 100644 index ade6624..0000000 --- a/content/posts/2022-10-14-blogsite.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -.title = "Blogsite", -.author = "Martin Ashby", -.date = @date("2022-10-14T22:59:01+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I was thinking about this blog and how it's set up. I [covered](posts/2021-10-01-blog/) the setup in a previous post, but it's quite simple: the site is generated from markdown files with [hugo](https://gohugo.io/) and published to git. The server pulls from git on a schedule, rebuilds it and copies it to the web server directory. - -I made a [little experiment](https://blogsite.mfashby.net/1-hello-new-blog) with a different approach [source](https://code.mfashby.net/martin/blogsite). Instead of statically generating the site, it's a Single Page Application which does the templating and routing on the client side. In theory this has a couple of upsides: if you visit multiple pages fewer bytes are transferred overall, and it totally removes the static site generation step; the folder is all just static content provided to the web server. This approach likely has some downsides too, like; requires javascript enabled client, no RSS feed or sitemap generation, and my implementation at least is relying on some fairly modern JS features like async/await and fetch API. - diff --git a/content/posts/2022-10-14-blogsite.smd b/content/posts/2022-10-14-blogsite.smd new file mode 100644 index 0000000..7b74c6a --- /dev/null +++ b/content/posts/2022-10-14-blogsite.smd @@ -0,0 +1,12 @@ +--- +.title = "Blogsite", +.author = "Martin Ashby", +.date = @date("2022-10-14T22:59:01+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I was thinking about this blog and how it's set up. I [covered](/posts/2021-10-01-blog/) the setup in a previous post, but it's quite simple: the site is generated from markdown files with [hugo](https://gohugo.io/) and published to git. The server pulls from git on a schedule, rebuilds it and copies it to the web server directory. + +I made a [little experiment](https://blogsite.mfashby.net/1-hello-new-blog) with a different approach [source](https://code.mfashby.net/martin/blogsite). Instead of statically generating the site, it's a Single Page Application which does the templating and routing on the client side. In theory this has a couple of upsides: if you visit multiple pages fewer bytes are transferred overall, and it totally removes the static site generation step; the folder is all just static content provided to the web server. This approach likely has some downsides too, like; requires javascript enabled client, no RSS feed or sitemap generation, and my implementation at least is relying on some fairly modern JS features like async/await and fetch API. + diff --git a/content/posts/2022-10-14-caddy.md b/content/posts/2022-10-14-caddy.md deleted file mode 100644 index 009bf53..0000000 --- a/content/posts/2022-10-14-caddy.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -.title = "Caddy", -.author = "Martin Ashby", -.date = @date("2022-10-14T22:58:22+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I switched to [caddy](https://caddywebserver.com) from nginx. Caddy has a 'simpler' configuration syntax, and offers built-in automatic TLS support with letsencrypt. I've also enabled automatic TLS support in [maddy](https://maddy.email) mail server, and I have been able to remove certbot entirely from my home server and disable the cron job that refreshed certs! - -The switch wasn't as painful as I thought it might be. It took about 45 minutes to read the caddy docs and port my existing nginx configuration over. Most of my sites are either simple static sites, or reverse proxies to other apps running their own web servers. - -This switch was prompted by a problem I've caused on my blog; I have put some large resources at my webserver root (e.g. /fooimage.jpg) instead of in a subfolder. In order to maintain external links, I wanted to move the images, and setup a permanent redirect to their new location. This is relatively difficult in nginx, and should be simpler in caddy. diff --git a/content/posts/2022-10-14-caddy.smd b/content/posts/2022-10-14-caddy.smd new file mode 100644 index 0000000..009bf53 --- /dev/null +++ b/content/posts/2022-10-14-caddy.smd @@ -0,0 +1,13 @@ +--- +.title = "Caddy", +.author = "Martin Ashby", +.date = @date("2022-10-14T22:58:22+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I switched to [caddy](https://caddywebserver.com) from nginx. Caddy has a 'simpler' configuration syntax, and offers built-in automatic TLS support with letsencrypt. I've also enabled automatic TLS support in [maddy](https://maddy.email) mail server, and I have been able to remove certbot entirely from my home server and disable the cron job that refreshed certs! + +The switch wasn't as painful as I thought it might be. It took about 45 minutes to read the caddy docs and port my existing nginx configuration over. Most of my sites are either simple static sites, or reverse proxies to other apps running their own web servers. + +This switch was prompted by a problem I've caused on my blog; I have put some large resources at my webserver root (e.g. /fooimage.jpg) instead of in a subfolder. In order to maintain external links, I wanted to move the images, and setup a permanent redirect to their new location. This is relatively difficult in nginx, and should be simpler in caddy. diff --git a/content/posts/2022-10-15-blogsite2.md b/content/posts/2022-10-15-blogsite2.md deleted file mode 100644 index ddb3e7b..0000000 --- a/content/posts/2022-10-15-blogsite2.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -.title = "Blogsite 2", -.author = "Martin Ashby", -.date = @date("2022-10-15T22:39:18+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I made another [small experiment](https://blogsite2.mfashby.net/) [source](https://code.mfashby.net/martin/blogsite2) to do my blog yet another way; rather than using hugo static site generation, I can leverage Caddy server's built-in [template rendering](https://caddyserver.com/docs/caddyfile/directives/templates) and markdown support to serve markdown files 'directly' without a pre-build step. - -In the end though, I will probably stick with static site generation. It offers some performance and security improvements such as no templating time, no possibility of vulnerabilities in the templating engine, in return for a little extra complexity having a build-step. diff --git a/content/posts/2022-10-15-blogsite2.smd b/content/posts/2022-10-15-blogsite2.smd new file mode 100644 index 0000000..ddb3e7b --- /dev/null +++ b/content/posts/2022-10-15-blogsite2.smd @@ -0,0 +1,11 @@ +--- +.title = "Blogsite 2", +.author = "Martin Ashby", +.date = @date("2022-10-15T22:39:18+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I made another [small experiment](https://blogsite2.mfashby.net/) [source](https://code.mfashby.net/martin/blogsite2) to do my blog yet another way; rather than using hugo static site generation, I can leverage Caddy server's built-in [template rendering](https://caddyserver.com/docs/caddyfile/directives/templates) and markdown support to serve markdown files 'directly' without a pre-build step. + +In the end though, I will probably stick with static site generation. It offers some performance and security improvements such as no templating time, no possibility of vulnerabilities in the templating engine, in return for a little extra complexity having a build-step. diff --git a/content/posts/2022-12-04-aoc.md b/content/posts/2022-12-04-aoc.md deleted file mode 100644 index 864f641..0000000 --- a/content/posts/2022-12-04-aoc.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -.title = "Advent of Code", -.author = "Martin Ashby", -.date = @date("2022-12-04T08:54:56Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I'm having a go at [Advent Of Code](https://adventofcode.com/2022) this year, this time [writing solutions in Rust](https://code.mfashby.net/martin/aoc2022). - -I have no chance at competing with [ChatGPT](https://github.com/max-sixty/aoc-gpt) though! diff --git a/content/posts/2022-12-04-aoc.smd b/content/posts/2022-12-04-aoc.smd new file mode 100644 index 0000000..864f641 --- /dev/null +++ b/content/posts/2022-12-04-aoc.smd @@ -0,0 +1,11 @@ +--- +.title = "Advent of Code", +.author = "Martin Ashby", +.date = @date("2022-12-04T08:54:56Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I'm having a go at [Advent Of Code](https://adventofcode.com/2022) this year, this time [writing solutions in Rust](https://code.mfashby.net/martin/aoc2022). + +I have no chance at competing with [ChatGPT](https://github.com/max-sixty/aoc-gpt) though! diff --git a/content/posts/2022-12-20-longboard-5.md b/content/posts/2022-12-20-longboard-5.md deleted file mode 100644 index da5ecf5..0000000 --- a/content/posts/2022-12-20-longboard-5.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -.title = "Longboard 5", -.author = "Martin Ashby", -.date = @date("2022-12-20T14:16:49Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I've been stuck inside with the cold weather recently. However, I've also discovered [Ampskate](https://www.ampskate.com/tricks) which is a great little guide for learning longboard dance and freestyle. - -Here's a little clip: - - - -Which is my attempt at a [cross-step](https://www.ampskate.com/tricks/cross-step). My goal is to learn the [ghostride kickflip](https://www.ampskate.com/tricks/ghostride-kickflip). \ No newline at end of file diff --git a/content/posts/2022-12-20-longboard-5.smd b/content/posts/2022-12-20-longboard-5.smd new file mode 100644 index 0000000..bb95b21 --- /dev/null +++ b/content/posts/2022-12-20-longboard-5.smd @@ -0,0 +1,17 @@ +--- +.title = "Longboard 5", +.author = "Martin Ashby", +.date = @date("2022-12-20T14:16:49Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I've been stuck inside with the cold weather recently. However, I've also discovered [Ampskate](https://www.ampskate.com/tricks) which is a great little guide for learning longboard dance and freestyle. + +Here's a little clip: + +```=html + +``` + +Which is my attempt at a [cross-step](https://www.ampskate.com/tricks/cross-step). My goal is to learn the [ghostride kickflip](https://www.ampskate.com/tricks/ghostride-kickflip). \ No newline at end of file diff --git a/content/posts/2022-12-26-spotifyd.md b/content/posts/2022-12-26-spotifyd.md deleted file mode 100644 index ded36f7..0000000 --- a/content/posts/2022-12-26-spotifyd.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -.title = "Spotifyd", -.author = "Martin Ashby", -.date = @date("2022-12-26T23:08:03Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I recently discovered [spotifyd](https://spotifyd.github.io/), an open source alternative to the deprecated libspotify. I happened to also have a [pi-zero W](https://www.raspberrypi.com/news/raspberry-pi-zero-w-joins-family/) from a while back, and a [pHAT DAC](https://learn.pimoroni.com/article/raspberry-pi-phat-dac-install) amplifier. - -It was a relatively trivial job to set up the pi zero w headless, get audio output to the pHAT DAC, install spotifyd and use it as a spotify connect device connected to my old [Cambridge Audio A1](http://www.hi-fi-insight.com/cambridge-audio-a1-integrated-amplifier.html). - -Install guides: -- [raspberry pi headless](https://www.raspberrypi.com/documentation/configuration/wireless/headless.md), since I last used this, userconf.txt was added which allows setting up a proper user with a unique password! Bonus security points. -- [spotifyd](https://spotifyd.github.io/spotifyd/installation/Raspberry-Pi.html), zero-w requires the arm-v6 variant, luckily they build releases for this architecture! Building on the pi-zero could take a while. -- [phat-dac](https://learn.pimoroni.com/article/raspberry-pi-phat-dac-install) -- [tailscale](https://tailscale.com/kb/1025/install-rpi/), not strictly necessary, but nice to have -- and [ufw](https://help.ubuntu.com/community/UFW) and [unattended-upgrade](https://manpages.ubuntu.com/manpages/bionic/man8/unattended-upgrade.8.html), just for the additional security and sanity. Note that you must set spotifyd to listen on a fixed port for disovery to work, and allow that port in the firewall! Specifically set `--zeroconf-port ` either via command line or in the configuration file, and allow connections with `sudo ufw allow ` - -I tried a similar project a few years ago, using [MPD](https://www.musicpd.org/) and spotify plugin, but at the time it was too unreliable. Thanks to the folks who spent the time creating spotifyd! - -I should get a case for the pi some time, at the moment it's just freely sitting on the shelf next to the speakers. - diff --git a/content/posts/2022-12-26-spotifyd.smd b/content/posts/2022-12-26-spotifyd.smd new file mode 100644 index 0000000..ded36f7 --- /dev/null +++ b/content/posts/2022-12-26-spotifyd.smd @@ -0,0 +1,23 @@ +--- +.title = "Spotifyd", +.author = "Martin Ashby", +.date = @date("2022-12-26T23:08:03Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I recently discovered [spotifyd](https://spotifyd.github.io/), an open source alternative to the deprecated libspotify. I happened to also have a [pi-zero W](https://www.raspberrypi.com/news/raspberry-pi-zero-w-joins-family/) from a while back, and a [pHAT DAC](https://learn.pimoroni.com/article/raspberry-pi-phat-dac-install) amplifier. + +It was a relatively trivial job to set up the pi zero w headless, get audio output to the pHAT DAC, install spotifyd and use it as a spotify connect device connected to my old [Cambridge Audio A1](http://www.hi-fi-insight.com/cambridge-audio-a1-integrated-amplifier.html). + +Install guides: +- [raspberry pi headless](https://www.raspberrypi.com/documentation/configuration/wireless/headless.md), since I last used this, userconf.txt was added which allows setting up a proper user with a unique password! Bonus security points. +- [spotifyd](https://spotifyd.github.io/spotifyd/installation/Raspberry-Pi.html), zero-w requires the arm-v6 variant, luckily they build releases for this architecture! Building on the pi-zero could take a while. +- [phat-dac](https://learn.pimoroni.com/article/raspberry-pi-phat-dac-install) +- [tailscale](https://tailscale.com/kb/1025/install-rpi/), not strictly necessary, but nice to have +- and [ufw](https://help.ubuntu.com/community/UFW) and [unattended-upgrade](https://manpages.ubuntu.com/manpages/bionic/man8/unattended-upgrade.8.html), just for the additional security and sanity. Note that you must set spotifyd to listen on a fixed port for disovery to work, and allow that port in the firewall! Specifically set `--zeroconf-port ` either via command line or in the configuration file, and allow connections with `sudo ufw allow ` + +I tried a similar project a few years ago, using [MPD](https://www.musicpd.org/) and spotify plugin, but at the time it was too unreliable. Thanks to the folks who spent the time creating spotifyd! + +I should get a case for the pi some time, at the moment it's just freely sitting on the shelf next to the speakers. + diff --git a/content/posts/2022-12-30-comments.md b/content/posts/2022-12-30-comments.md deleted file mode 100644 index e6aa9b8..0000000 --- a/content/posts/2022-12-30-comments.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -.title = "Comments", -.author = "Martin Ashby", -.date = @date("2022-12-30T17:53:00Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I've added an extremely basic, probably insecure, comments form to my blog site. I've built it in Rust for practice. Code is [here](https://code.mfashby.net/martin/mfashby.net/src/branch/main/comments). - -It uses [askama](https://docs.rs/askama/latest/askama/) templates, [axum](https://docs.rs/axum/latest/axum/) web framework, [sqlx](https://docs.rs/sqlx/latest/sqlx/) for database access, and postgres database. - -Askama offers compile-time validation of templates since it actually compiles the template to code, and sqlx does compile-time checking of SQL queries and generation of ad-hoc structs for convenience when reading data. These were both very efficient at catching coding errors I made. Axum is an async web framework from the same developers as tokio, the Rust aync runtime. So far it seems easy to use. I already had postgres running on my pi for some other server software, and I've extensive experience with it at work, so it was an easy choice. - -It runs on my raspberry pi, and it cross-compiles from my x86_64 desktop or my aarch64 laptop. The former was fiddly since at least one crate dependency (ring) includes some C code, so an appropriate C cross compiler must be installed and supplied to cargo/rustc at build time. - -At the moment it doesn't include CSRF protection, and the capcha is basic. It also doesn't notify me when new comments are added. These are future features I might add. It also stores comments keyed by the URL of the page they are made on. This is flexible; no additional configuration is required to enable comments on posts, but also fragile: if a post moves for some reason, I'll lose the comments until I update them on the database. Since I don't usually move posts, I can live with this for now. diff --git a/content/posts/2022-12-30-comments.smd b/content/posts/2022-12-30-comments.smd new file mode 100644 index 0000000..e6aa9b8 --- /dev/null +++ b/content/posts/2022-12-30-comments.smd @@ -0,0 +1,17 @@ +--- +.title = "Comments", +.author = "Martin Ashby", +.date = @date("2022-12-30T17:53:00Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I've added an extremely basic, probably insecure, comments form to my blog site. I've built it in Rust for practice. Code is [here](https://code.mfashby.net/martin/mfashby.net/src/branch/main/comments). + +It uses [askama](https://docs.rs/askama/latest/askama/) templates, [axum](https://docs.rs/axum/latest/axum/) web framework, [sqlx](https://docs.rs/sqlx/latest/sqlx/) for database access, and postgres database. + +Askama offers compile-time validation of templates since it actually compiles the template to code, and sqlx does compile-time checking of SQL queries and generation of ad-hoc structs for convenience when reading data. These were both very efficient at catching coding errors I made. Axum is an async web framework from the same developers as tokio, the Rust aync runtime. So far it seems easy to use. I already had postgres running on my pi for some other server software, and I've extensive experience with it at work, so it was an easy choice. + +It runs on my raspberry pi, and it cross-compiles from my x86_64 desktop or my aarch64 laptop. The former was fiddly since at least one crate dependency (ring) includes some C code, so an appropriate C cross compiler must be installed and supplied to cargo/rustc at build time. + +At the moment it doesn't include CSRF protection, and the capcha is basic. It also doesn't notify me when new comments are added. These are future features I might add. It also stores comments keyed by the URL of the page they are made on. This is flexible; no additional configuration is required to enable comments on posts, but also fragile: if a post moves for some reason, I'll lose the comments until I update them on the database. Since I don't usually move posts, I can live with this for now. diff --git a/content/posts/2022-12-31-cgit.md b/content/posts/2022-12-31-cgit.md deleted file mode 100644 index 3ef1fe7..0000000 --- a/content/posts/2022-12-31-cgit.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -.title = "Cgit", -.author = "Martin Ashby", -.date = @date("2022-12-31T23:39:38Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -In a [previous post](posts/2022-09-25-back-to-git/) I switched back from fossil to git. I found [gitea](https://gitea.io/) to be a pretty good server. However, it has many features I do not use, and it takes a minimum of 15% of the RAM on my Raspberry Pi home server! I found a simpler setup. - -I have switched to plain git server accessed with SSH, which [git-scm](https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server) documents how to set up. I'd still like a web UI to allow others to see and download my code. [Cgit](https://wiki.archlinux.org/title/Cgit) is a simple web user interface for multiple git repositories. It runs as a CGI application, and I use caddy web server, so thanks to [Luke Hsiao's blog post](https://luke.hsiao.dev/blog/cgit-caddy-gitolite/) and [Andras Schneider's Caddy CGI plugin](https://github.com/aksdb/caddy-cgi) I managed to get it running fairly easily. - -One hitch was adding git LFS support. I use git LFS for some media files on my blog. Gitea includes git LFS support out of the box, but a plain git server does not. I am using the standalone [reference server](https://github.com/git-lfs/lfs-test-server). This has a disclaimer that it's not 'production ready', but since I'm running this behind tailscale I'm reasonably happy it's ok. - -A second hitch was figuring out how to redirect from old repo locations to new ones, so I don't have to update every link in my blog. New repo locations simply don't have the `/martin` prefix. This seemed difficult in caddy, until I found [this post](https://caddy.community/t/modify-uri-and-then-redirect/16686/4) and I wound up with the following configuration, which seems to work well: -``` - ... - handle /martin* { - route { - uri strip_prefix /martin - redir https://{host}{uri} - } - } - ... -``` \ No newline at end of file diff --git a/content/posts/2022-12-31-cgit.smd b/content/posts/2022-12-31-cgit.smd new file mode 100644 index 0000000..b2895f8 --- /dev/null +++ b/content/posts/2022-12-31-cgit.smd @@ -0,0 +1,25 @@ +--- +.title = "Cgit", +.author = "Martin Ashby", +.date = @date("2022-12-31T23:39:38Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +In a [previous post](/posts/2022-09-25-back-to-git/) I switched back from fossil to git. I found [gitea](https://gitea.io/) to be a pretty good server. However, it has many features I do not use, and it takes a minimum of 15% of the RAM on my Raspberry Pi home server! I found a simpler setup. + +I have switched to plain git server accessed with SSH, which [git-scm](https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server) documents how to set up. I'd still like a web UI to allow others to see and download my code. [Cgit](https://wiki.archlinux.org/title/Cgit) is a simple web user interface for multiple git repositories. It runs as a CGI application, and I use caddy web server, so thanks to [Luke Hsiao's blog post](https://luke.hsiao.dev/blog/cgit-caddy-gitolite/) and [Andras Schneider's Caddy CGI plugin](https://github.com/aksdb/caddy-cgi) I managed to get it running fairly easily. + +One hitch was adding git LFS support. I use git LFS for some media files on my blog. Gitea includes git LFS support out of the box, but a plain git server does not. I am using the standalone [reference server](https://github.com/git-lfs/lfs-test-server). This has a disclaimer that it's not 'production ready', but since I'm running this behind tailscale I'm reasonably happy it's ok. + +A second hitch was figuring out how to redirect from old repo locations to new ones, so I don't have to update every link in my blog. New repo locations simply don't have the `/martin` prefix. This seemed difficult in caddy, until I found [this post](https://caddy.community/t/modify-uri-and-then-redirect/16686/4) and I wound up with the following configuration, which seems to work well: +``` + ... + handle /martin* { + route { + uri strip_prefix /martin + redir https://{host}{uri} + } + } + ... +``` \ No newline at end of file diff --git a/content/posts/2023-01-31-oso.md b/content/posts/2023-01-31-oso.md deleted file mode 100644 index bbb916f..0000000 --- a/content/posts/2023-01-31-oso.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -.title = "Authorization and search operations", -.author = "Martin Ashby", -.date = @date("2023-01-31T21:14:06Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -Background: at work I help to build a [SAAS](https://en.wikipedia.org/wiki/Software_as_a_service) web application for healthcare. An important aspect of our web application is [authorization](https://csrc.nist.gov/glossary/term/authorization). It's a pretty hard problem, because the business has a fairly complex set of rules about who can see what data. The rules involve attributes of the [subject](https://csrc.nist.gov/glossary/term/subject) and [object](https://csrc.nist.gov/glossary/term/object), and the direct or indirect (e.g. via a group) relationship between them. It's also a pretty important problem; healthcare data is typically very sensitive and we need to obey the law and keep our users' trust in order to provide useful services. The problem is also constrained by speed; in order to render a web page in a reasonable time e.g. under a second, data must be fetched and authorized in just a few milliseconds. - -One way to imagine authorization is as a function: `allow(subject, action, object)` which returns a simple boolean for permitted or not permitted. The 'action' would typically be 'create', 'read', 'update' or 'delete', but it could be something else for more complex operations. This post is going to explore 'read', and more specifically 'search' operations because they are extremely common and they introduce some complexity that can be tackled in several different ways. - -Logically a 'search' might be considered the same as a 'read' since the end result is the same: returning the data to the requestor. It might then be reasonable to expect the same authorization rules apply. The difference is that in a 'read' operation, the requestor already knows how many results they're expecting and has some kind of unique identifier for that data, wheras in a 'search' operation they don't know in advance how many results they will get, or what the unique identifiers are for that data. This has an impact on the implementation of those authorization rules. - -Authorizing a read operation can be quite simple: it's possible to have an actual function which is executed after fetching the data from storage, and if the read isn't allowed then return an error, e.g. an [HTTP 403](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403) error would be appropriate for a web-based API. -```rust -fn read_foo(subject, foo_id) -> Result { - let data: Foo = fetch_foo(foo_id); - if !allow(subject, "read", data) { - Err(Error::Forbidden) - } else { - Ok(data) - } -} -``` - -Authorizing a search operation is more complicated since we don't know how many objects we will actually receive. A naïve solution is to simply filter unauthorized results from the set. -```rust -fn search_foo(subject, criteria) -> Result> { - fetch_foos(criteria) - .filter(|data| {allow(subject, "read", data)}) - .collect() -} -``` -This solution has several issues. Firstly leakage: redacted results leak the fact that there was something to redact. By making repeated searches and varying the criteria, it's possible for someone to figure out some attributes of the hidden data. Secondly paging: redacting results can trigger unpleasant edge cases e.g. a whole page of redacted results, which can be a poor experience if those pages are supposed to be presented to an end user. Thirdly efficiency: someone might issue a query for many results they can't see amd our application might fetch and process a bunch of data, only for most of that work to be thrown away by filtering. Despite these disadvantages, post-filtering is an attractive option becuase it is simple, read and search operations can be authorized in the same way, even using the same function. - -An alternative approach is to bake authorization rules into queries; e.g. if the application's storage is a database, then authorization might become part of an SQL query. -```rust -fn search_foo(subject, criteria) -> Result> { - let new_criteria = add_criteria_for_authz("foo", subject, criteria); - fetch_foos(criteria) -} -``` -This solution also has downsides, notably there is no longer code sharing between read and search operations. If the rules change, both the `allow` and `add_criteria_for_authz` functions must be updated. - -A variation on this approach which preserves a implementation for read and search is possible using [Oso](https://docs.osohq.com/). The Oso policy evaluation engine is capable of _partially_ evaluating a function, and instead of emitting a simple boolean it returns a set of constraints which must be met to ensure the data fetch is authorized. Those constraints might be turned into query parameters for the underlying storage. This approach is called [data filtering](https://docs.osohq.com/guides/data_filtering.html) in Oso's documentation. Code for it might look like this: -```rust -fn search_foo(subject, criteria) -> Result> { - let constraints = allow(subject, "read", Variable{}); - let query = add_constraints(criteria, constraints); - fetch_foo(query) -} -``` -Our 'allow' function can now be shared between read operations where it receives the real object, and searches where it receives a variable and returns constraints. The downside of this approach is the complexity of the add_constraints function. We might end up in a situation where it's not possible to turn some complicated set of constraints into a reasonable query. - -A completely different approach is to push the authorization check further down the stack. Most storage engines offer some kind of authorization facility. Postgresql database has an extensive permission system, as well as [row security policies](https://www.postgresql.org/docs/current/ddl-rowsecurity.html). These could be used to implement authorization policies independently of any queries an application might issue. There are a couple of advantages to this approach. Firstly; arbitrary queries can be authorized. This means authorization happens even if the application layer is bypassed e.g. by a statistics gathering process or manual query. Secondly; queries can be simpler for the developer to write. This is especially useful when joins are involved. If authorization is implemented as part of the query itself, then security policies for both tables involved in the join have to be combined somehow. If row level security is used however, then the postgresql execution planner handles applying the relevant policies to each table, and the developer's query can remain simple. - -One downside to this approach is that it's very specific to the storage implementation. If an application has to support multiple storage backends e.g. mysql database or a plain filesystem, then the implementation will be very different for each one. Another downside is the expression of authorization rules: postgresql row level security policies are implemented as SQL queries which must return 'true' or 'false' and have a few built-in variables available. These policies may not be easy to read and test, and they certainly aren't portable across different systems. - -I made a quick [experiment](https://github.com/mfashby/rls_oso) to invoke Oso's authorization engine from postgresql row level security policy. This is an attempt to keep the advantages of row level security and mitigate one of the downsides It should be possible to define access control policies in Oso's policy language. The policies themselves are no longer defined in a database-specific language and might be re-used in other contexts, as well as tested independently of the database. This does introduce an additional downside that it requires customization of the postgresql installation, which may be undesirable in some circumstances. - -Related articles -- [attribute based access control](https://en.wikipedia.org/wiki/Attribute-based_access_control) -- [relationship based access control](https://en.wikipedia.org/wiki/Relationship-based_access_control) diff --git a/content/posts/2023-01-31-oso.smd b/content/posts/2023-01-31-oso.smd new file mode 100644 index 0000000..bbb916f --- /dev/null +++ b/content/posts/2023-01-31-oso.smd @@ -0,0 +1,64 @@ +--- +.title = "Authorization and search operations", +.author = "Martin Ashby", +.date = @date("2023-01-31T21:14:06Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +Background: at work I help to build a [SAAS](https://en.wikipedia.org/wiki/Software_as_a_service) web application for healthcare. An important aspect of our web application is [authorization](https://csrc.nist.gov/glossary/term/authorization). It's a pretty hard problem, because the business has a fairly complex set of rules about who can see what data. The rules involve attributes of the [subject](https://csrc.nist.gov/glossary/term/subject) and [object](https://csrc.nist.gov/glossary/term/object), and the direct or indirect (e.g. via a group) relationship between them. It's also a pretty important problem; healthcare data is typically very sensitive and we need to obey the law and keep our users' trust in order to provide useful services. The problem is also constrained by speed; in order to render a web page in a reasonable time e.g. under a second, data must be fetched and authorized in just a few milliseconds. + +One way to imagine authorization is as a function: `allow(subject, action, object)` which returns a simple boolean for permitted or not permitted. The 'action' would typically be 'create', 'read', 'update' or 'delete', but it could be something else for more complex operations. This post is going to explore 'read', and more specifically 'search' operations because they are extremely common and they introduce some complexity that can be tackled in several different ways. + +Logically a 'search' might be considered the same as a 'read' since the end result is the same: returning the data to the requestor. It might then be reasonable to expect the same authorization rules apply. The difference is that in a 'read' operation, the requestor already knows how many results they're expecting and has some kind of unique identifier for that data, wheras in a 'search' operation they don't know in advance how many results they will get, or what the unique identifiers are for that data. This has an impact on the implementation of those authorization rules. + +Authorizing a read operation can be quite simple: it's possible to have an actual function which is executed after fetching the data from storage, and if the read isn't allowed then return an error, e.g. an [HTTP 403](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403) error would be appropriate for a web-based API. +```rust +fn read_foo(subject, foo_id) -> Result { + let data: Foo = fetch_foo(foo_id); + if !allow(subject, "read", data) { + Err(Error::Forbidden) + } else { + Ok(data) + } +} +``` + +Authorizing a search operation is more complicated since we don't know how many objects we will actually receive. A naïve solution is to simply filter unauthorized results from the set. +```rust +fn search_foo(subject, criteria) -> Result> { + fetch_foos(criteria) + .filter(|data| {allow(subject, "read", data)}) + .collect() +} +``` +This solution has several issues. Firstly leakage: redacted results leak the fact that there was something to redact. By making repeated searches and varying the criteria, it's possible for someone to figure out some attributes of the hidden data. Secondly paging: redacting results can trigger unpleasant edge cases e.g. a whole page of redacted results, which can be a poor experience if those pages are supposed to be presented to an end user. Thirdly efficiency: someone might issue a query for many results they can't see amd our application might fetch and process a bunch of data, only for most of that work to be thrown away by filtering. Despite these disadvantages, post-filtering is an attractive option becuase it is simple, read and search operations can be authorized in the same way, even using the same function. + +An alternative approach is to bake authorization rules into queries; e.g. if the application's storage is a database, then authorization might become part of an SQL query. +```rust +fn search_foo(subject, criteria) -> Result> { + let new_criteria = add_criteria_for_authz("foo", subject, criteria); + fetch_foos(criteria) +} +``` +This solution also has downsides, notably there is no longer code sharing between read and search operations. If the rules change, both the `allow` and `add_criteria_for_authz` functions must be updated. + +A variation on this approach which preserves a implementation for read and search is possible using [Oso](https://docs.osohq.com/). The Oso policy evaluation engine is capable of _partially_ evaluating a function, and instead of emitting a simple boolean it returns a set of constraints which must be met to ensure the data fetch is authorized. Those constraints might be turned into query parameters for the underlying storage. This approach is called [data filtering](https://docs.osohq.com/guides/data_filtering.html) in Oso's documentation. Code for it might look like this: +```rust +fn search_foo(subject, criteria) -> Result> { + let constraints = allow(subject, "read", Variable{}); + let query = add_constraints(criteria, constraints); + fetch_foo(query) +} +``` +Our 'allow' function can now be shared between read operations where it receives the real object, and searches where it receives a variable and returns constraints. The downside of this approach is the complexity of the add_constraints function. We might end up in a situation where it's not possible to turn some complicated set of constraints into a reasonable query. + +A completely different approach is to push the authorization check further down the stack. Most storage engines offer some kind of authorization facility. Postgresql database has an extensive permission system, as well as [row security policies](https://www.postgresql.org/docs/current/ddl-rowsecurity.html). These could be used to implement authorization policies independently of any queries an application might issue. There are a couple of advantages to this approach. Firstly; arbitrary queries can be authorized. This means authorization happens even if the application layer is bypassed e.g. by a statistics gathering process or manual query. Secondly; queries can be simpler for the developer to write. This is especially useful when joins are involved. If authorization is implemented as part of the query itself, then security policies for both tables involved in the join have to be combined somehow. If row level security is used however, then the postgresql execution planner handles applying the relevant policies to each table, and the developer's query can remain simple. + +One downside to this approach is that it's very specific to the storage implementation. If an application has to support multiple storage backends e.g. mysql database or a plain filesystem, then the implementation will be very different for each one. Another downside is the expression of authorization rules: postgresql row level security policies are implemented as SQL queries which must return 'true' or 'false' and have a few built-in variables available. These policies may not be easy to read and test, and they certainly aren't portable across different systems. + +I made a quick [experiment](https://github.com/mfashby/rls_oso) to invoke Oso's authorization engine from postgresql row level security policy. This is an attempt to keep the advantages of row level security and mitigate one of the downsides It should be possible to define access control policies in Oso's policy language. The policies themselves are no longer defined in a database-specific language and might be re-used in other contexts, as well as tested independently of the database. This does introduce an additional downside that it requires customization of the postgresql installation, which may be undesirable in some circumstances. + +Related articles +- [attribute based access control](https://en.wikipedia.org/wiki/Attribute-based_access_control) +- [relationship based access control](https://en.wikipedia.org/wiki/Relationship-based_access_control) diff --git a/content/posts/2023-02-05-book-site-reliability-engineering.md b/content/posts/2023-02-05-book-site-reliability-engineering.md deleted file mode 100644 index 3224968..0000000 --- a/content/posts/2023-02-05-book-site-reliability-engineering.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -.title = "Book - Site Reliability Engineering", -.author = "Martin Ashby", -.date = @date("2023-02-05T15:53:43Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I've read [Site Reliability Engineering](https://sre.google/sre-book/table-of-contents/) (SRE) from Google/O'Reilly. It's an interesting insight into how Google scales their operations work. - -A core theme of the book is ensuring that 'operations' work i.e. managing servers, computers, networks, hardware and applications scales [sub-linearly](https://stackoverflow.com/questions/32311924/what-are-sublinear-algorithms) with both the number of users of a service, and the number of services the company provides. The book is really a series of shorter articles about how Google accomplishes this through technology, business processes and personal interactions. - -A lot of the guidance in the book seems more applicable at large scales (100s of engineers) rather than smaller organizations. For example; configuring extensive monitoring to check services are meeting their 'service level objectives' (SLOs) and alert when they're not can be lots of work, especially if the objectives are not extremely well defined to begin with. It can be hard to justify this work alongside delivering the actual minimum product which will satisfy the customer demand. That's not to say monitoring should be ignored completely until later, but getting monitoring done 'right' to the standard shown in the book is likely out of reach for organizations without dedicated SRE team. - -Some advice seems useful regardless of scale, for instance holding meaningful post-mortems on incidents, and having at least some basic incident response plans. - -The real take-away messsage for me is: outsourcing as much as possible. When SRE isn't your core capability, use hosted or fully managed services wherever possible and leave the operations work to companies that specialize in it. This might be public cloud services like Amazon Web Services or Google Cloud Platform, however in my experience those platforms still end up requiring dedicated teams to manage them; for example managing Identity & Access Management (IAM) can get complex very quickly. Using 'infrastructure as code' (IAC) tools like terraform can help to keep the complexity under control, but these tools bring their own cognitive overhead as well. - -Services which offer to handle _all_ the infrastructure concerns, like [darklang](https://darklang.com) or [shuttle.rs](https;//shuttle.rs), or [webapp.io](https://webapp.io/) are very attractive for this reason. See my previous post on ['serverless'](https://mfashby.net/posts/2022-09-09-serverless/) for some thoughts about those! If I was to have a great idea for a web-based SAAS and I built it, I would likely choose to use one of these services; probably shuttle.rs. \ No newline at end of file diff --git a/content/posts/2023-02-05-book-site-reliability-engineering.smd b/content/posts/2023-02-05-book-site-reliability-engineering.smd new file mode 100644 index 0000000..ef4b457 --- /dev/null +++ b/content/posts/2023-02-05-book-site-reliability-engineering.smd @@ -0,0 +1,19 @@ +--- +.title = "Book - Site Reliability Engineering", +.author = "Martin Ashby", +.date = @date("2023-02-05T15:53:43Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I've read [Site Reliability Engineering](https://sre.google/sre-book/table-of-contents/) (SRE) from Google/O'Reilly. It's an interesting insight into how Google scales their operations work. + +A core theme of the book is ensuring that 'operations' work i.e. managing servers, computers, networks, hardware and applications scales [sub-linearly](https://stackoverflow.com/questions/32311924/what-are-sublinear-algorithms) with both the number of users of a service, and the number of services the company provides. The book is really a series of shorter articles about how Google accomplishes this through technology, business processes and personal interactions. + +A lot of the guidance in the book seems more applicable at large scales (100s of engineers) rather than smaller organizations. For example; configuring extensive monitoring to check services are meeting their 'service level objectives' (SLOs) and alert when they're not can be lots of work, especially if the objectives are not extremely well defined to begin with. It can be hard to justify this work alongside delivering the actual minimum product which will satisfy the customer demand. That's not to say monitoring should be ignored completely until later, but getting monitoring done 'right' to the standard shown in the book is likely out of reach for organizations without dedicated SRE team. + +Some advice seems useful regardless of scale, for instance holding meaningful post-mortems on incidents, and having at least some basic incident response plans. + +The real take-away messsage for me is: outsourcing as much as possible. When SRE isn't your core capability, use hosted or fully managed services wherever possible and leave the operations work to companies that specialize in it. This might be public cloud services like Amazon Web Services or Google Cloud Platform, however in my experience those platforms still end up requiring dedicated teams to manage them; for example managing Identity & Access Management (IAM) can get complex very quickly. Using 'infrastructure as code' (IAC) tools like terraform can help to keep the complexity under control, but these tools bring their own cognitive overhead as well. + +Services which offer to handle _all_ the infrastructure concerns, like [darklang](https://darklang.com) or [shuttle.rs](https://shuttle.rs), or [webapp.io](https://webapp.io/) are very attractive for this reason. See my previous post on ['serverless'](https://mfashby.net/posts/2022-09-09-serverless/) for some thoughts about those! If I was to have a great idea for a web-based SAAS and I built it, I would likely choose to use one of these services; probably shuttle.rs. \ No newline at end of file diff --git a/content/posts/2023-02-05-semantic-dissonance.md b/content/posts/2023-02-05-semantic-dissonance.md deleted file mode 100644 index 30ea99f..0000000 --- a/content/posts/2023-02-05-semantic-dissonance.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -.title = "Semantic Dissonance", -.author = "Martin Ashby", -.date = @date("2023-02-05T16:38:55Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -A while ago I read [Enterprise Integration Patterns](https://www.enterpriseintegrationpatterns.com/). It was too long ago to write a review, however the phrase that I first encountered in that book and has stuck with me since is 'semantic dissonance'. In the field of software development, this means that we have two (or more!) _incompatible_ models of the same real-world situation. This happens a lot in healthcare IT. The latest and greatest standard for data exchange is [Fast Healthcare Interoperability Records](https://hl7.org/fhir/) (FHIR). Many healthcare IT suppliers are being pushed towards exposing their data over this standardised format, and they have to handle mapping from their own internal models to the standard and back again. These mappings are sometimes irreversible, i.e. mapping forward then backward again does not result in the same exact result as the input. They might also be lossy; i.e. a concept exists in one model which does not exist in the other at all, or a concept with a similar meaning but subtly different exists. - -It's the same problem as human language translation, but in machine form. I expect it occurs in many other fields of human endeavour too. \ No newline at end of file diff --git a/content/posts/2023-02-05-semantic-dissonance.smd b/content/posts/2023-02-05-semantic-dissonance.smd new file mode 100644 index 0000000..30ea99f --- /dev/null +++ b/content/posts/2023-02-05-semantic-dissonance.smd @@ -0,0 +1,11 @@ +--- +.title = "Semantic Dissonance", +.author = "Martin Ashby", +.date = @date("2023-02-05T16:38:55Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +A while ago I read [Enterprise Integration Patterns](https://www.enterpriseintegrationpatterns.com/). It was too long ago to write a review, however the phrase that I first encountered in that book and has stuck with me since is 'semantic dissonance'. In the field of software development, this means that we have two (or more!) _incompatible_ models of the same real-world situation. This happens a lot in healthcare IT. The latest and greatest standard for data exchange is [Fast Healthcare Interoperability Records](https://hl7.org/fhir/) (FHIR). Many healthcare IT suppliers are being pushed towards exposing their data over this standardised format, and they have to handle mapping from their own internal models to the standard and back again. These mappings are sometimes irreversible, i.e. mapping forward then backward again does not result in the same exact result as the input. They might also be lossy; i.e. a concept exists in one model which does not exist in the other at all, or a concept with a similar meaning but subtly different exists. + +It's the same problem as human language translation, but in machine form. I expect it occurs in many other fields of human endeavour too. \ No newline at end of file diff --git a/content/posts/2023-04-09-designing-data-intensive-applications.md b/content/posts/2023-04-09-designing-data-intensive-applications.md deleted file mode 100644 index 24ab2f0..0000000 --- a/content/posts/2023-04-09-designing-data-intensive-applications.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -.title = "Book - Designing Data Intensive Applications", -.author = "Martin Ashby", -.date = @date("2023-04-09T21:45:01+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -[Link](https://www.oreilly.com/library/view/designing-data-intensive-applications/9781491903063/) to the book. - -The book starts by describing very simple key-value database systems; then gradually introduces more concepts and features like indexes, joins, SQL (Structured Query Language), MapReduce, isolation, consensus, total order broadcast and so on, eventually winding up with data streaming systems. At each stage, [the author](https://martin.kleppmann.com/) explains the problems that such systems solve and the trade-offs that they make. The book does not dive too deeply into the algorithms that such systems use, although it does describe some key ones. The examples are typically based on existing data products, which is somewhat useful for discovery and comparison if you might be designing a data system. The earlier parts of the book covering database internals is interesting but at first seems somewhat unrelated to later parts; however in the later parts the author draws parallels between the internal workings of a database and data streaming systems. In particular he predicts an 'unbundling' of database features like replication and secondary indexes to allow greater flexibility and integration of systems which are most suited for particular jobs. - -The author is keen to point out that although more complex data systems can offer horizontal scalability, that these should be weighed against the additional complexity they bring to your system. I agree with this approach. - -Overall I found the book useful. It covered some concepts I only had a passing familiarity with such as [MapReduce](https://en.wikipedia.org/wiki/MapReduce) and it really made me think about the problems we might face in our systems at work and their potential solutions. I would recommend it to most software engineers, in particular those who might be designing systems that work with data that won't fit on a single computer. diff --git a/content/posts/2023-04-09-designing-data-intensive-applications.smd b/content/posts/2023-04-09-designing-data-intensive-applications.smd new file mode 100644 index 0000000..24ab2f0 --- /dev/null +++ b/content/posts/2023-04-09-designing-data-intensive-applications.smd @@ -0,0 +1,15 @@ +--- +.title = "Book - Designing Data Intensive Applications", +.author = "Martin Ashby", +.date = @date("2023-04-09T21:45:01+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +[Link](https://www.oreilly.com/library/view/designing-data-intensive-applications/9781491903063/) to the book. + +The book starts by describing very simple key-value database systems; then gradually introduces more concepts and features like indexes, joins, SQL (Structured Query Language), MapReduce, isolation, consensus, total order broadcast and so on, eventually winding up with data streaming systems. At each stage, [the author](https://martin.kleppmann.com/) explains the problems that such systems solve and the trade-offs that they make. The book does not dive too deeply into the algorithms that such systems use, although it does describe some key ones. The examples are typically based on existing data products, which is somewhat useful for discovery and comparison if you might be designing a data system. The earlier parts of the book covering database internals is interesting but at first seems somewhat unrelated to later parts; however in the later parts the author draws parallels between the internal workings of a database and data streaming systems. In particular he predicts an 'unbundling' of database features like replication and secondary indexes to allow greater flexibility and integration of systems which are most suited for particular jobs. + +The author is keen to point out that although more complex data systems can offer horizontal scalability, that these should be weighed against the additional complexity they bring to your system. I agree with this approach. + +Overall I found the book useful. It covered some concepts I only had a passing familiarity with such as [MapReduce](https://en.wikipedia.org/wiki/MapReduce) and it really made me think about the problems we might face in our systems at work and their potential solutions. I would recommend it to most software engineers, in particular those who might be designing systems that work with data that won't fit on a single computer. diff --git a/content/posts/2023-06-16-bike.md b/content/posts/2023-06-16-bike.md deleted file mode 100644 index 4f66111..0000000 --- a/content/posts/2023-06-16-bike.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -.title = "Bike 2", -.author = "Martin Ashby", -.date = @date("2023-06-16T21:04:31+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I haven't posted about my bike for a while; there have been a couple of changes. - -Firstly; the [freehub](https://en.wikipedia.org/wiki/Freehub) broke, which put it out of action completely until I could get it to the shop. It wound up being cheaper to get a replacement wheel than try to fix the freehub, and since the rims were worn anyway it was an easy choice. The tyres had also perished slightly, so I opted for some new ones, this time hybrids. These make a _huge_ difference to on-road cycling, it's now far easier to pedal! - -The other difference is a recently purchased [followme tandem](https://www.thelittlebikecompany.co.uk/product/followme-tandem/) set to connect my daughter's bike to mine. She is outgrowing the seat on my cycle but she's too young to ride on roads and not confident to ride her own yet. The followme seems like a good bridge to get her used to pedalling and having her own seat, but we can still cover a good distance for a day out. I was inspired by the review from [cyclesprog](https://www.cyclesprog.co.uk/carrying-kids-on-bikes/bike-towbars/followme-cycle-hitch-full-review/). We tested it out today with a friend! - -![Myself and daughter on followme tandem, friend on road cycle](bike2.jpg) - diff --git a/content/posts/2023-06-16-bike.smd b/content/posts/2023-06-16-bike.smd new file mode 100644 index 0000000..4f66111 --- /dev/null +++ b/content/posts/2023-06-16-bike.smd @@ -0,0 +1,16 @@ +--- +.title = "Bike 2", +.author = "Martin Ashby", +.date = @date("2023-06-16T21:04:31+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I haven't posted about my bike for a while; there have been a couple of changes. + +Firstly; the [freehub](https://en.wikipedia.org/wiki/Freehub) broke, which put it out of action completely until I could get it to the shop. It wound up being cheaper to get a replacement wheel than try to fix the freehub, and since the rims were worn anyway it was an easy choice. The tyres had also perished slightly, so I opted for some new ones, this time hybrids. These make a _huge_ difference to on-road cycling, it's now far easier to pedal! + +The other difference is a recently purchased [followme tandem](https://www.thelittlebikecompany.co.uk/product/followme-tandem/) set to connect my daughter's bike to mine. She is outgrowing the seat on my cycle but she's too young to ride on roads and not confident to ride her own yet. The followme seems like a good bridge to get her used to pedalling and having her own seat, but we can still cover a good distance for a day out. I was inspired by the review from [cyclesprog](https://www.cyclesprog.co.uk/carrying-kids-on-bikes/bike-towbars/followme-cycle-hitch-full-review/). We tested it out today with a friend! + +![Myself and daughter on followme tandem, friend on road cycle](bike2.jpg) + diff --git a/content/posts/2023-08-11-4-eyes.md b/content/posts/2023-08-11-4-eyes.md deleted file mode 100644 index 9ba3f60..0000000 --- a/content/posts/2023-08-11-4-eyes.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -.title = "Four Eyes", -.author = "Martin Ashby", -.date = @date("2023-08-11T22:50:43+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -The four-eyes principle (also known as [two-man rule](https://en.wikipedia.org/wiki/Two-man_rule) or no-lone-zone) stipulates that for certain very critical operations like the launch of a nuclear weapon or the handling of very sensitive cryptographic key material, at least two qualified persons must be actively involved. - -I think the same principle should hold true in some IT operations work; for example some servers are running software that is both very important to keep running, and is also handling very sensitive data. Examples might be banking or healthcare services. A mistake or malice while operating this software can be very harmful. For example: causing significant [downtime for a healthcare system](https://www.bbc.co.uk/news/uk-england-london-62308447) can result in degraded level of care for patients in hospitals. Another example: [leaking details of police staff](https://www.bbc.co.uk/news/uk-northern-ireland-66467164) can result in serious harm to those staff. - -I work for a fully-remote software company which handles healthcare data and provides live services using that data. One additional challenge of fully-remote working is securing access to servers. Remote access to servers is a hard requirement: in order to do my job I must access servers that run our software. However, this means that the security of those servers is only as good as my own [physical security](https://xkcd.com/538/). - -There is a hole in the market for a remote 'four-eyes' system. My boss suggested something as 'simple' as an SSH server which requires _two_ separate authorized users to access, and where every shell command must be confirmed by both users before executing. This means at least _two_ system administrators must be compromised (or complicit) in order for a breach to occur. In theory this is significantly less likely than a single administrator being compromised. - -There are [packages](https://pkg.go.dev/golang.org/x/crypto/ssh) for Go and other programming languages which implement the SSH protocol, and I think it's possible to implement such a server. It's something I plan to explore. diff --git a/content/posts/2023-08-11-4-eyes.smd b/content/posts/2023-08-11-4-eyes.smd new file mode 100644 index 0000000..9ba3f60 --- /dev/null +++ b/content/posts/2023-08-11-4-eyes.smd @@ -0,0 +1,17 @@ +--- +.title = "Four Eyes", +.author = "Martin Ashby", +.date = @date("2023-08-11T22:50:43+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +The four-eyes principle (also known as [two-man rule](https://en.wikipedia.org/wiki/Two-man_rule) or no-lone-zone) stipulates that for certain very critical operations like the launch of a nuclear weapon or the handling of very sensitive cryptographic key material, at least two qualified persons must be actively involved. + +I think the same principle should hold true in some IT operations work; for example some servers are running software that is both very important to keep running, and is also handling very sensitive data. Examples might be banking or healthcare services. A mistake or malice while operating this software can be very harmful. For example: causing significant [downtime for a healthcare system](https://www.bbc.co.uk/news/uk-england-london-62308447) can result in degraded level of care for patients in hospitals. Another example: [leaking details of police staff](https://www.bbc.co.uk/news/uk-northern-ireland-66467164) can result in serious harm to those staff. + +I work for a fully-remote software company which handles healthcare data and provides live services using that data. One additional challenge of fully-remote working is securing access to servers. Remote access to servers is a hard requirement: in order to do my job I must access servers that run our software. However, this means that the security of those servers is only as good as my own [physical security](https://xkcd.com/538/). + +There is a hole in the market for a remote 'four-eyes' system. My boss suggested something as 'simple' as an SSH server which requires _two_ separate authorized users to access, and where every shell command must be confirmed by both users before executing. This means at least _two_ system administrators must be compromised (or complicit) in order for a breach to occur. In theory this is significantly less likely than a single administrator being compromised. + +There are [packages](https://pkg.go.dev/golang.org/x/crypto/ssh) for Go and other programming languages which implement the SSH protocol, and I think it's possible to implement such a server. It's something I plan to explore. diff --git a/content/posts/2023-08-22-comments-2.md b/content/posts/2023-08-22-comments-2.md deleted file mode 100644 index d5d6225..0000000 --- a/content/posts/2023-08-22-comments-2.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -.title = "Comments 2", -.author = "Martin Ashby", -.date = @date("2023-08-22T14:48:41+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -[Previously](/posts/2022-12-30-comments/) I added a basic comment system to my website using a separate web server which served only the comment HTML. This is fine, but it does require another program running continuously on my server. Since that server is a raspberry pi, and it is running a lot of other software as well, and my blog doesn't get a lot of hits (let alone comments), I thought I could do better by using the [Common Gateway Interface (CGI)](https://en.wikipedia.org/wiki/Common_Gateway_Interface). CGI doesn't require a daemon program, but instead will launch a program to generate dynamic content when someone loads the page. In this way, no memory or CPU is required until an actual page is requested. The downside is that a new process is launched for each page load, but I think that's an OK trade-off for me. I already have CGI configured on my web server for running [cgit](/posts/2022-12-31-cgit/). - -I also wanted to explore the [zig](ziglang.org/) programming language some more by writing an actual program with it, so I chose to rewrite it in zig. - -I made a [quick exploratory program](https://code.mfashby.net/cgifun/about/) just to remind myself how CGI works in Caddy, then I ported my original comments app to a [CGI app](https://code.mfashby.net/mfashby.net/tree/comments). The new app has far fewer dependencies since it doesn't embed a web server or web framework. It depends on the [zig standard library](https://ziglang.org/documentation/master/std/), [libpq](https://www.postgresql.org/docs/current/libpq.html), [mustache-zig](https://github.com/batiati/mustache-zig) and some of my own shared code from another project to do page routing. - -The new comments app works just the same as the old one, although with some loss of functionality - it no longer emails me when a new comment is posted. I plan to implement this, however the zig ecosystem is much less mature than rust right now, and I could not find a good email library so I might end up rolling my own. - -Another spin-off from this project could be a pure-zig postgres database library. Libpq is great, however it's a C library and requires linking the C standard library, and makes code less easily portable to other platforms. The [pgx](https://github.com/jackc/pgx) project shows that it's possible to have a pure-go postgresql driver, and this might be inspiration for a zig version. Another advantage of using the host language rather than the C library is making use of future [asynchronous capabilities](https://ziglearn.org/chapter-5/). \ No newline at end of file diff --git a/content/posts/2023-08-22-comments-2.smd b/content/posts/2023-08-22-comments-2.smd new file mode 100644 index 0000000..c75b3d4 --- /dev/null +++ b/content/posts/2023-08-22-comments-2.smd @@ -0,0 +1,17 @@ +--- +.title = "Comments 2", +.author = "Martin Ashby", +.date = @date("2023-08-22T14:48:41+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +[Previously](/posts/2022-12-30-comments/) I added a basic comment system to my website using a separate web server which served only the comment HTML. This is fine, but it does require another program running continuously on my server. Since that server is a raspberry pi, and it is running a lot of other software as well, and my blog doesn't get a lot of hits (let alone comments), I thought I could do better by using the [Common Gateway Interface (CGI)](https://en.wikipedia.org/wiki/Common_Gateway_Interface). CGI doesn't require a daemon program, but instead will launch a program to generate dynamic content when someone loads the page. In this way, no memory or CPU is required until an actual page is requested. The downside is that a new process is launched for each page load, but I think that's an OK trade-off for me. I already have CGI configured on my web server for running [cgit](/posts/2022-12-31-cgit). + +I also wanted to explore the [zig](https://ziglang.org/) programming language some more by writing an actual program with it, so I chose to rewrite it in zig. + +I made a [quick exploratory program](https://code.mfashby.net/cgifun/about/) just to remind myself how CGI works in Caddy, then I ported my original comments app to a [CGI app](https://code.mfashby.net/mfashby.net/tree/comments). The new app has far fewer dependencies since it doesn't embed a web server or web framework. It depends on the [zig standard library](https://ziglang.org/documentation/master/std/), [libpq](https://www.postgresql.org/docs/current/libpq.html), [mustache-zig](https://github.com/batiati/mustache-zig) and some of my own shared code from another project to do page routing. + +The new comments app works just the same as the old one, although with some loss of functionality - it no longer emails me when a new comment is posted. I plan to implement this, however the zig ecosystem is much less mature than rust right now, and I could not find a good email library so I might end up rolling my own. + +Another spin-off from this project could be a pure-zig postgres database library. Libpq is great, however it's a C library and requires linking the C standard library, and makes code less easily portable to other platforms. The [pgx](https://github.com/jackc/pgx) project shows that it's possible to have a pure-go postgresql driver, and this might be inspiration for a zig version. Another advantage of using the host language rather than the C library is making use of future [asynchronous capabilities](https://ziglearn.org/chapter-5/). \ No newline at end of file diff --git a/content/posts/2023-09-12-mcl.md b/content/posts/2023-09-12-mcl.md deleted file mode 100644 index 60f9e25..0000000 --- a/content/posts/2023-09-12-mcl.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -.title = "Mcl (minecraft launcher)", -.author = "Martin Ashby", -.date = @date("2023-09-12T07:03:15+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I wrote a [minecraft launcher](https://code.mfashby.net/mcl/about/) in [zig](ziglang.org/) as a learning exercise. - -I got a lot of practice writing zig code and I learned a few things about it. - -- The [GeneralPurposeAllocator](https://ziglang.org/documentation/master/std/#A;std:heap.GeneralPurposeAllocator) is really useful for finding memory leaks, as is the std.testing.allocator for use in tests. -- The standard library HTTP client is really cool, but unfortunately fails on a lot of websites because it lacks TLSv1.2 support. -- Calling into C code is really easy. I used [libCURL](https://curl.se/libcurl/) instead of the zig stdlib and it was easy to write a wrapper around it. -- The standard library JSON parsing is good, but error messages are not verbose enough to help you and by default they don't indicate _where_ in the tree the problem is. This can be added but it's not obvious how to do it (spoiler: set the .diagnostics element on a std.json.Scanner). For types which the standard library can't cope with, there is an escape hatch: implement jsonParse method for that type. -- The builtin module has useful constants for checking the current operating system and CPU architecture, which I used for hacking in linux-aarch64 support. - -Finally however, I learned that minecraft on the pinebook pro sucks :( It's just not got enough power to run the game well. \ No newline at end of file diff --git a/content/posts/2023-09-12-mcl.smd b/content/posts/2023-09-12-mcl.smd new file mode 100644 index 0000000..a372fe2 --- /dev/null +++ b/content/posts/2023-09-12-mcl.smd @@ -0,0 +1,19 @@ +--- +.title = "Mcl (minecraft launcher)", +.author = "Martin Ashby", +.date = @date("2023-09-12T07:03:15+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I wrote a [minecraft launcher](https://code.mfashby.net/mcl/about/) in [zig](https://ziglang.org/) as a learning exercise. + +I got a lot of practice writing zig code and I learned a few things about it. + +- The [GeneralPurposeAllocator](https://ziglang.org/documentation/master/std/#A;std:heap.GeneralPurposeAllocator) is really useful for finding memory leaks, as is the std.testing.allocator for use in tests. +- The standard library HTTP client is really cool, but unfortunately fails on a lot of websites because it lacks TLSv1.2 support. +- Calling into C code is really easy. I used [libCURL](https://curl.se/libcurl/) instead of the zig stdlib and it was easy to write a wrapper around it. +- The standard library JSON parsing is good, but error messages are not verbose enough to help you and by default they don't indicate _where_ in the tree the problem is. This can be added but it's not obvious how to do it (spoiler: set the .diagnostics element on a std.json.Scanner). For types which the standard library can't cope with, there is an escape hatch: implement jsonParse method for that type. +- The builtin module has useful constants for checking the current operating system and CPU architecture, which I used for hacking in linux-aarch64 support. + +Finally however, I learned that minecraft on the pinebook pro sucks :( It's just not got enough power to run the game well. \ No newline at end of file diff --git a/content/posts/2023-10-01-parable-of-the-sower.md b/content/posts/2023-10-01-parable-of-the-sower.md deleted file mode 100644 index 23ad3a0..0000000 --- a/content/posts/2023-10-01-parable-of-the-sower.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -.title = "Book - Parable of the Sower / Parable of the Talents", -.author = "Martin Ashby", -.date = @date("2023-10-01T22:23:00+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -By [Octavia E Butler](https://en.wikipedia.org/wiki/Octavia_E._Butler). *Note, spoilers* - -When I read fiction, I primarily read sci-fi. Some of my favourite authors include Iain M Banks, Terry Pratchett, Steven Baxter. I also enjoyed Frank Herbert's original Dune series, and some of Issac Asimov's short stories (particularly I Robot). - -'Parable of the Sower' stood out to me in my local library's tiny sci-fi section; I'd not previously read anything by Octavia E Butler. It doesn't tread lightly: racism, sexism, violence, abuse and slavery are core themes, in a story where North America is tearing itself apart over a generation through crime, fear, and disorder. The protagonist Lauren Olamina suffers immensely, and yet she holds onto a dream of not only improving her own situation but changing the whole outlook of humanity; setting us on a course for the stars. The epilogue of the latter book sees an elderley Olamina watch the first starships launched through her organisation's work. - -I enjoyed the story immensely, although the brutality made it difficult to enjoy the book. Butler herself said at interview that the research for the novel was ['overwhelming'](https://web.archive.org/web/20051112234721/http://www.democracynow.org/article.pl?sid=05%2F11%2F11%2F158201), and her writing took a more light-hearted turn rather than continuing this series. diff --git a/content/posts/2023-10-01-parable-of-the-sower.smd b/content/posts/2023-10-01-parable-of-the-sower.smd new file mode 100644 index 0000000..23ad3a0 --- /dev/null +++ b/content/posts/2023-10-01-parable-of-the-sower.smd @@ -0,0 +1,15 @@ +--- +.title = "Book - Parable of the Sower / Parable of the Talents", +.author = "Martin Ashby", +.date = @date("2023-10-01T22:23:00+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +By [Octavia E Butler](https://en.wikipedia.org/wiki/Octavia_E._Butler). *Note, spoilers* + +When I read fiction, I primarily read sci-fi. Some of my favourite authors include Iain M Banks, Terry Pratchett, Steven Baxter. I also enjoyed Frank Herbert's original Dune series, and some of Issac Asimov's short stories (particularly I Robot). + +'Parable of the Sower' stood out to me in my local library's tiny sci-fi section; I'd not previously read anything by Octavia E Butler. It doesn't tread lightly: racism, sexism, violence, abuse and slavery are core themes, in a story where North America is tearing itself apart over a generation through crime, fear, and disorder. The protagonist Lauren Olamina suffers immensely, and yet she holds onto a dream of not only improving her own situation but changing the whole outlook of humanity; setting us on a course for the stars. The epilogue of the latter book sees an elderley Olamina watch the first starships launched through her organisation's work. + +I enjoyed the story immensely, although the brutality made it difficult to enjoy the book. Butler herself said at interview that the research for the novel was ['overwhelming'](https://web.archive.org/web/20051112234721/http://www.democracynow.org/article.pl?sid=05%2F11%2F11%2F158201), and her writing took a more light-hearted turn rather than continuing this series. diff --git a/content/posts/2023-10-07-zipdl.md b/content/posts/2023-10-07-zipdl.md deleted file mode 100644 index 7e91a88..0000000 --- a/content/posts/2023-10-07-zipdl.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -.title = "Zipdl", -.author = "Martin Ashby", -.date = @date("2023-10-07T23:28:16+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I wrote a small program for downloading individual files from a remote ZIP file on a http server that supports [Range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range) requests. This was an interesting learning exercise. - -[Project page](/projects/zipdl) \ No newline at end of file diff --git a/content/posts/2023-10-07-zipdl.smd b/content/posts/2023-10-07-zipdl.smd new file mode 100644 index 0000000..7e91a88 --- /dev/null +++ b/content/posts/2023-10-07-zipdl.smd @@ -0,0 +1,11 @@ +--- +.title = "Zipdl", +.author = "Martin Ashby", +.date = @date("2023-10-07T23:28:16+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I wrote a small program for downloading individual files from a remote ZIP file on a http server that supports [Range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range) requests. This was an interesting learning exercise. + +[Project page](/projects/zipdl) \ No newline at end of file diff --git a/content/posts/2023-11-25-roc.md b/content/posts/2023-11-25-roc.md deleted file mode 100644 index 626d972..0000000 --- a/content/posts/2023-11-25-roc.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -.title = "Roc", -.author = "Martin Ashby", -.date = @date("2023-11-25T21:19:27Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I had a go at [writing some code](https://code.mfashby.net/roctorrent/tree/main.roc) in the [Roc](https://www.roc-lang.org/) programming language. It's a functional programming language, which is statically typed, and compiled to a standalone executable. I first heard about it after listening to an interview with it's author on the [Legacy Code Rocks](https://legacycode.rocks/) podcast, and later thought about it again after seeing a comment about it on [hacker news](https://news.ycombinator.com/). - -I found it pretty easy to use. I've previously had a go at Haskell and Clojure, so I'm familiar with functional programming, but I've never been entirely comfortable with it. Roc is fairly new, and definitely rough around the edges. I had to compile it from source as there was no binary for linux-aarch64. I ran into a [couple](https://github.com/roc-lang/roc/issues/6085) of [issues](https://github.com/roc-lang/roc/issues/6084) as well while I was coding. - -Nothing else to report yet, I definitely need some more time with it before I can say anything more interesting! \ No newline at end of file diff --git a/content/posts/2023-11-25-roc.smd b/content/posts/2023-11-25-roc.smd new file mode 100644 index 0000000..626d972 --- /dev/null +++ b/content/posts/2023-11-25-roc.smd @@ -0,0 +1,13 @@ +--- +.title = "Roc", +.author = "Martin Ashby", +.date = @date("2023-11-25T21:19:27Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I had a go at [writing some code](https://code.mfashby.net/roctorrent/tree/main.roc) in the [Roc](https://www.roc-lang.org/) programming language. It's a functional programming language, which is statically typed, and compiled to a standalone executable. I first heard about it after listening to an interview with it's author on the [Legacy Code Rocks](https://legacycode.rocks/) podcast, and later thought about it again after seeing a comment about it on [hacker news](https://news.ycombinator.com/). + +I found it pretty easy to use. I've previously had a go at Haskell and Clojure, so I'm familiar with functional programming, but I've never been entirely comfortable with it. Roc is fairly new, and definitely rough around the edges. I had to compile it from source as there was no binary for linux-aarch64. I ran into a [couple](https://github.com/roc-lang/roc/issues/6085) of [issues](https://github.com/roc-lang/roc/issues/6084) as well while I was coding. + +Nothing else to report yet, I definitely need some more time with it before I can say anything more interesting! \ No newline at end of file diff --git a/content/posts/2023-11-26-skateboard-2.md b/content/posts/2023-11-26-skateboard-2.md deleted file mode 100644 index d49ce84..0000000 --- a/content/posts/2023-11-26-skateboard-2.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -.title = "Skateboard 2", -.author = "Martin Ashby", -.date = @date("2023-11-26T20:33:27Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I've been skating indoors at [LS-ten skatepark](https://ls-ten.org/) recently, as the poor weather over the last few weeks has made outdoor skating... not fun. I've mostly abandoned my shorter board in favour of the [Lush Throttle](https://lushlongboards.com/buy/throttle/). At 34" length it's not too much longer than a typical 'popsicle' board, but I find it much more comfortable. I don't mind the lack of double kicktail, and I prefer the longer wheelbase. - -I've been working on the basics of skating ramps and bowls - drop-ins, roll-ins, kick turns, rock-to-fakie, and tail stall; and I'm still quite rough as you can see in the following video. I hope to continue skating regularly and improving. - - - -(on a technical note, I've signed up for a peertube instance and I'm posting my skate videos there. I have the content backed up locally as well, but I figured I might avoid hosting videos from my home server for now) \ No newline at end of file diff --git a/content/posts/2023-11-26-skateboard-2.smd b/content/posts/2023-11-26-skateboard-2.smd new file mode 100644 index 0000000..767f4ec --- /dev/null +++ b/content/posts/2023-11-26-skateboard-2.smd @@ -0,0 +1,17 @@ +--- +.title = "Skateboard 2", +.author = "Martin Ashby", +.date = @date("2023-11-26T20:33:27Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I've been skating indoors at [LS-ten skatepark](https://ls-ten.org/) recently, as the poor weather over the last few weeks has made outdoor skating... not fun. I've mostly abandoned my shorter board in favour of the [Lush Throttle](https://lushlongboards.com/buy/throttle/). At 34" length it's not too much longer than a typical 'popsicle' board, but I find it much more comfortable. I don't mind the lack of double kicktail, and I prefer the longer wheelbase. + +I've been working on the basics of skating ramps and bowls - drop-ins, roll-ins, kick turns, rock-to-fakie, and tail stall; and I'm still quite rough as you can see in the following video. I hope to continue skating regularly and improving. + +```=html + +``` + +(on a technical note, I've signed up for a peertube instance and I'm posting my skate videos there. I have the content backed up locally as well, but I figured I might avoid hosting videos from my home server for now) \ No newline at end of file diff --git a/content/posts/2023-12-01-aoc2023.md b/content/posts/2023-12-01-aoc2023.md deleted file mode 100644 index 383dca5..0000000 --- a/content/posts/2023-12-01-aoc2023.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -.title = "Advent of Code 2023", -.author = "Martin Ashby", -.date = @date("2023-12-01T21:42:21Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I'm doing [Advent of Code](https://adventofcode.com) again this year, this time in [Zig](https://ziglang.org). - -I'm posting the code [here](https://code.mfashby.net/aoc2023/tree). - diff --git a/content/posts/2023-12-01-aoc2023.smd b/content/posts/2023-12-01-aoc2023.smd new file mode 100644 index 0000000..383dca5 --- /dev/null +++ b/content/posts/2023-12-01-aoc2023.smd @@ -0,0 +1,12 @@ +--- +.title = "Advent of Code 2023", +.author = "Martin Ashby", +.date = @date("2023-12-01T21:42:21Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I'm doing [Advent of Code](https://adventofcode.com) again this year, this time in [Zig](https://ziglang.org). + +I'm posting the code [here](https://code.mfashby.net/aoc2023/tree). + diff --git a/content/posts/2024-01-26-data-oriented-design.md b/content/posts/2024-01-26-data-oriented-design.md deleted file mode 100644 index 0b16419..0000000 --- a/content/posts/2024-01-26-data-oriented-design.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -.title = "Book - Data Oriented Design", -.author = "Martin Ashby", -.date = @date("2024-01-26T20:19:31Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I recently read [Data Oriented Design](https://www.dataorienteddesign.com/dodbook/) by Richard Fabian. - -The book is about software design; and specifically it relates to software design in games, but the principals are partially relevant to other domains as well. - -The main take away seems to be that 'Object Oriented Design' fails to deliver on some of the properties that software engineers think it will give their projects, as well as being hurtful for performance in general due to it's inherent incompatibility with how modern CPUs work. The remedy is 'Data Oriented Design' which advocates _separating_ data from behaviour, normalizing your data in the same way that you would in a relational database system, and processing in bulk rather than jumping back and forth between tasks. - -There were some paragraphs on _why_ object oriented programming is bad for performance; and the answer is that it's bad for pipelining and branch prediction, mainly becuase of C++ virtual functions which branch and then have to do pointer lookups in order to find which code to execute, which means pipelining is ineffective. The same problem exists in theory in other programming languages which use inheritance. - -Although it was an interesting read, I don't think it'll have much impact on how I think about software that I work on. At my company we are working on a web application which does not have the same stringent low-level performance requirements as video games do. We also use an external relational database rather than having local application state, and code we write uses a minimum amount of local state. There were some interesting points about database normal forms and how they are useful for extensibility which are relevant to me, and I'll be taking those on board. In future my work might involve more data processing, where performance is more of a concern, so I might end up revisiting this book. \ No newline at end of file diff --git a/content/posts/2024-01-26-data-oriented-design.smd b/content/posts/2024-01-26-data-oriented-design.smd new file mode 100644 index 0000000..0b16419 --- /dev/null +++ b/content/posts/2024-01-26-data-oriented-design.smd @@ -0,0 +1,17 @@ +--- +.title = "Book - Data Oriented Design", +.author = "Martin Ashby", +.date = @date("2024-01-26T20:19:31Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I recently read [Data Oriented Design](https://www.dataorienteddesign.com/dodbook/) by Richard Fabian. + +The book is about software design; and specifically it relates to software design in games, but the principals are partially relevant to other domains as well. + +The main take away seems to be that 'Object Oriented Design' fails to deliver on some of the properties that software engineers think it will give their projects, as well as being hurtful for performance in general due to it's inherent incompatibility with how modern CPUs work. The remedy is 'Data Oriented Design' which advocates _separating_ data from behaviour, normalizing your data in the same way that you would in a relational database system, and processing in bulk rather than jumping back and forth between tasks. + +There were some paragraphs on _why_ object oriented programming is bad for performance; and the answer is that it's bad for pipelining and branch prediction, mainly becuase of C++ virtual functions which branch and then have to do pointer lookups in order to find which code to execute, which means pipelining is ineffective. The same problem exists in theory in other programming languages which use inheritance. + +Although it was an interesting read, I don't think it'll have much impact on how I think about software that I work on. At my company we are working on a web application which does not have the same stringent low-level performance requirements as video games do. We also use an external relational database rather than having local application state, and code we write uses a minimum amount of local state. There were some interesting points about database normal forms and how they are useful for extensibility which are relevant to me, and I'll be taking those on board. In future my work might involve more data processing, where performance is more of a concern, so I might end up revisiting this book. \ No newline at end of file diff --git a/content/posts/2024-01-26-dyn.md b/content/posts/2024-01-26-dyn.md deleted file mode 100644 index 3eaf189..0000000 --- a/content/posts/2024-01-26-dyn.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -.title = "Dynamic DNS", -.author = "Martin Ashby", -.date = @date("2024-01-26T00:02:35Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I recently upgraded my home broadband, however in the process I lost my static IP address. I have requested a new one, but in the meantime I wrote a [program](https://code.mfashby.net/do-dyn/file/src/main.zig.html) to dynamically update my DNS records in case my router restarts and my WAN IP address changes. - -I didn't really want to change providers in order to move to a proper dynamic DNS setup, since this is a temporary solution, but I did enjoy writing a little code to make it work with my current DNS provider (digital ocean). I appreciate how useful it is to have an HTTP client in the zig standard library! - -New broadband is now [fibre to the premises](https://en.wikipedia.org/wiki/Fiber_to_the_x), and it's quite a lot quicker. diff --git a/content/posts/2024-01-26-dyn.smd b/content/posts/2024-01-26-dyn.smd new file mode 100644 index 0000000..3eaf189 --- /dev/null +++ b/content/posts/2024-01-26-dyn.smd @@ -0,0 +1,13 @@ +--- +.title = "Dynamic DNS", +.author = "Martin Ashby", +.date = @date("2024-01-26T00:02:35Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I recently upgraded my home broadband, however in the process I lost my static IP address. I have requested a new one, but in the meantime I wrote a [program](https://code.mfashby.net/do-dyn/file/src/main.zig.html) to dynamically update my DNS records in case my router restarts and my WAN IP address changes. + +I didn't really want to change providers in order to move to a proper dynamic DNS setup, since this is a temporary solution, but I did enjoy writing a little code to make it work with my current DNS provider (digital ocean). I appreciate how useful it is to have an HTTP client in the zig standard library! + +New broadband is now [fibre to the premises](https://en.wikipedia.org/wiki/Fiber_to_the_x), and it's quite a lot quicker. diff --git a/content/posts/2024-02-01-1brc.md b/content/posts/2024-02-01-1brc.md deleted file mode 100644 index a38c637..0000000 --- a/content/posts/2024-02-01-1brc.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -.title = "1brc", -.author = "Martin Ashby", -.date = @date("2024-02-01T13:58:47Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I [had a go](https://code.mfashby.net/z1brc/file/src/main.zig.html) at the [One Billion Row Challenge](https://github.com/gunnarmorling/1brc), but in Zig rather than Java. - -I got down to about 10 seconds :) the leading java solution runs in 2 seconds on my desktop machine (and that's without speedup from using GraalVM) diff --git a/content/posts/2024-02-01-1brc.smd b/content/posts/2024-02-01-1brc.smd new file mode 100644 index 0000000..a38c637 --- /dev/null +++ b/content/posts/2024-02-01-1brc.smd @@ -0,0 +1,11 @@ +--- +.title = "1brc", +.author = "Martin Ashby", +.date = @date("2024-02-01T13:58:47Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I [had a go](https://code.mfashby.net/z1brc/file/src/main.zig.html) at the [One Billion Row Challenge](https://github.com/gunnarmorling/1brc), but in Zig rather than Java. + +I got down to about 10 seconds :) the leading java solution runs in 2 seconds on my desktop machine (and that's without speedup from using GraalVM) diff --git a/content/posts/2024-02-05-phones.md b/content/posts/2024-02-05-phones.md deleted file mode 100644 index d68a6a9..0000000 --- a/content/posts/2024-02-05-phones.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -.title = "Fairphone", -.author = "Martin Ashby", -.date = @date("2024-02-05T19:56:17Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I bought a [fairphone 4](https://shop.fairphone.com/fairphone-4) just under 2 years ago. I'm pleased to say last week I repaired it! I had accidentally filled the pocket on my jeans with sand on holiday, and then I put the phone in the pocket. The USB-C on the bottom of the phone got sand in it, and stopped holding a cable correctly. It just about worked for charging still, but the cable would pop out very easily, and this was pretty inconvenient. I tried a few ways to clear it out, with no success. - -I bought a replacement part, and (after some delivery issues, which were the fault of the local shop doing UPS delivery, not fairphone's fault) I got a new USB-C socket that I fit in 10 minutes with a single crosspoint screwdriver. - -I really appreciate how repairable this phone seems to be. The battery is replaceable without a screwdriver, and even the display is replaceable. I hope this will allow me to keep the phone for a long time. \ No newline at end of file diff --git a/content/posts/2024-02-05-phones.smd b/content/posts/2024-02-05-phones.smd new file mode 100644 index 0000000..d68a6a9 --- /dev/null +++ b/content/posts/2024-02-05-phones.smd @@ -0,0 +1,13 @@ +--- +.title = "Fairphone", +.author = "Martin Ashby", +.date = @date("2024-02-05T19:56:17Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I bought a [fairphone 4](https://shop.fairphone.com/fairphone-4) just under 2 years ago. I'm pleased to say last week I repaired it! I had accidentally filled the pocket on my jeans with sand on holiday, and then I put the phone in the pocket. The USB-C on the bottom of the phone got sand in it, and stopped holding a cable correctly. It just about worked for charging still, but the cable would pop out very easily, and this was pretty inconvenient. I tried a few ways to clear it out, with no success. + +I bought a replacement part, and (after some delivery issues, which were the fault of the local shop doing UPS delivery, not fairphone's fault) I got a new USB-C socket that I fit in 10 minutes with a single crosspoint screwdriver. + +I really appreciate how repairable this phone seems to be. The battery is replaceable without a screwdriver, and even the display is replaceable. I hope this will allow me to keep the phone for a long time. \ No newline at end of file diff --git a/content/posts/2024-03-01-communication.md b/content/posts/2024-03-01-communication.md deleted file mode 100644 index b321739..0000000 --- a/content/posts/2024-03-01-communication.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -.title = "Communication", -.author = "Martin Ashby", -.date = @date("2024-03-01T14:40:50Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I believe that in software development, being open and working in the open are crucial to wellbeing and efficiency; even moreso when working remotely. There are 3 things that I think should be communicated: intention, struggle, and progress. Communications should be clear, public, searchable, and regular. This post explains my thoughts on the subject. - -## Intent -Communicating your intent ensures that you are aligned with your colleagues. If I write something like "I intend to fix this N+1 query problem in the billing service to reduce page-load times, which will improve our users' experience with billing and reduce our resource usage", this could elicit a couple of different possible responses from colleagues. A couple of examples follow: - -A project manager who has attended a recent strategy meeting might chime in: "oh, didn't you hear last week? We're no longer billing customers any more, so that service will be deprecated soon!". This example is contrived; a decision to stop billing customers would probably be widely advertised throughout the company. However, I think that no single person can know every piece of relevant information in a medium to large company, and by advertising your intentions you can re-align yourself with your colleagues early enough to avoid wasted effort. - -An alternative scenario might play out like this: a co-developer says "don't bother fixing N+1 issues, we're switching that program to use SQLite so the roundtrip inefficiency of N+1 queries will be negligable". At this point I and the other developer might discuss these two alternative solutions to the problem at hand, and come to some agreement about what the best approach is before either of us starts to actually work on the solution. - -This isn't foolproof - it might happen that nobody with the right additional context reads your message, so you go ahead and do the work anyway, and it turns out to be wasted. However, with this approach I think it happens often enough that wasted effort or conflicts are caught early and resolved, to make it worth your time writing a few messages about what you intend to do and why. - -## Struggles -Communicating your struggles ensures that you don't stay stuck on a problem that someone else has already solved. If I write something like "I tried to fix the N+1 problem, but now 50% of page loads are experiencing FooException, and I can't see why yet", then a knowledgable colleague might pop up and say "oh, I've seen FooException happen when you ask the database for too many rows with an IN clause". - -Of course, before writing the message you should probably _search_ your company's chat for FooException. You might also search StackOverflow or Reddit (or wherever you get your advice from on the internet). If your colleagues are taking the same approach to communication, you now have some additional clues without interrupting anyone else or waiting for a response. This is why I think chat needs to be searchable. - -Sometimes you are the first person to see a particular problem. In this case, writing about it is a great way for the _next_ person to encounter that problem to get some clues about it. That next person might be yourself in a few months or years. If the problem is with something that's open source, you should also write about it on the internet somewhere: maybe file an issue on the project's public issue tracker, ask a question on StackOverflow, even post on your own blog; anything that is searchable. - -[Linus' Law](https://en.wikipedia.org/wiki/Linus%27s_law) is phrased as "given enough eyeballs, all bugs are shallow"; even just one pair of additional eyeballs on a problem has a good chance of making it easier to solve. By writing about your struggles, you are putting problems in front of more eyeballs. - -I think that personal struggles should be communicated as well. If my kids are sick and I have to take a couple of hours away from work to care for them, it's better that my colleagues know that instead of getting frustrated when I don't answer. Be reasonable with this though, people are very variable in how much they want to share about their lives and hear about your life. It's probably better to leave it at "I'm going to the doctor" instead of going into detail on your nasty rash. - - -## Progress -Communicating your progress ensures that both you (and your boss) know where you are. This is important to keep the project managers happy, and they in turn keep the stakeholders happy (well, at least informed if not actually happy). Communicating your progress can also make you feel good. Especially milestones; it's worth giving your colleagues and yourself a pat on the back when you hit some significant point in a project. - - -## Downsides & Difficulties -This style of communicating is not a panacea, and there may be significant downsides. For example: your boss might decide to fire you for taking off for an hour a week to look after your grandma's cat. If you had kept quiet, you would have kept your job. Although this example is facetious, it's easy to imagine situations where exposed misalignment causes more friction than simply not communicating. - -Some people find it uncomfortable to communicate openly about things they are struggling with, because they fear being seen as incompetent. This is a valid concern. - -In both of these examples, I think the problem is the environment, rather than the communication style. Open communication makes you vulnerable, so if your environment is hostile rather than supportive then you will suffer for it. - -## Conclusions -I am fortunate enough to work in a very supportive environment, so I try to communicate openly and publicly for all the benefits listed above. So far this is working well. - -Disclaimer - absolutely none of this is scientific. I have no measurements or data to back up what I'm saying here, and I have not even gone looking for existing literature on the subject. These are intuitions that I have built up from working in 2 quite different software companies for ~ 14 years. Take any advice with a big grain of salt. \ No newline at end of file diff --git a/content/posts/2024-03-01-communication.smd b/content/posts/2024-03-01-communication.smd new file mode 100644 index 0000000..b321739 --- /dev/null +++ b/content/posts/2024-03-01-communication.smd @@ -0,0 +1,46 @@ +--- +.title = "Communication", +.author = "Martin Ashby", +.date = @date("2024-03-01T14:40:50Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I believe that in software development, being open and working in the open are crucial to wellbeing and efficiency; even moreso when working remotely. There are 3 things that I think should be communicated: intention, struggle, and progress. Communications should be clear, public, searchable, and regular. This post explains my thoughts on the subject. + +## Intent +Communicating your intent ensures that you are aligned with your colleagues. If I write something like "I intend to fix this N+1 query problem in the billing service to reduce page-load times, which will improve our users' experience with billing and reduce our resource usage", this could elicit a couple of different possible responses from colleagues. A couple of examples follow: + +A project manager who has attended a recent strategy meeting might chime in: "oh, didn't you hear last week? We're no longer billing customers any more, so that service will be deprecated soon!". This example is contrived; a decision to stop billing customers would probably be widely advertised throughout the company. However, I think that no single person can know every piece of relevant information in a medium to large company, and by advertising your intentions you can re-align yourself with your colleagues early enough to avoid wasted effort. + +An alternative scenario might play out like this: a co-developer says "don't bother fixing N+1 issues, we're switching that program to use SQLite so the roundtrip inefficiency of N+1 queries will be negligable". At this point I and the other developer might discuss these two alternative solutions to the problem at hand, and come to some agreement about what the best approach is before either of us starts to actually work on the solution. + +This isn't foolproof - it might happen that nobody with the right additional context reads your message, so you go ahead and do the work anyway, and it turns out to be wasted. However, with this approach I think it happens often enough that wasted effort or conflicts are caught early and resolved, to make it worth your time writing a few messages about what you intend to do and why. + +## Struggles +Communicating your struggles ensures that you don't stay stuck on a problem that someone else has already solved. If I write something like "I tried to fix the N+1 problem, but now 50% of page loads are experiencing FooException, and I can't see why yet", then a knowledgable colleague might pop up and say "oh, I've seen FooException happen when you ask the database for too many rows with an IN clause". + +Of course, before writing the message you should probably _search_ your company's chat for FooException. You might also search StackOverflow or Reddit (or wherever you get your advice from on the internet). If your colleagues are taking the same approach to communication, you now have some additional clues without interrupting anyone else or waiting for a response. This is why I think chat needs to be searchable. + +Sometimes you are the first person to see a particular problem. In this case, writing about it is a great way for the _next_ person to encounter that problem to get some clues about it. That next person might be yourself in a few months or years. If the problem is with something that's open source, you should also write about it on the internet somewhere: maybe file an issue on the project's public issue tracker, ask a question on StackOverflow, even post on your own blog; anything that is searchable. + +[Linus' Law](https://en.wikipedia.org/wiki/Linus%27s_law) is phrased as "given enough eyeballs, all bugs are shallow"; even just one pair of additional eyeballs on a problem has a good chance of making it easier to solve. By writing about your struggles, you are putting problems in front of more eyeballs. + +I think that personal struggles should be communicated as well. If my kids are sick and I have to take a couple of hours away from work to care for them, it's better that my colleagues know that instead of getting frustrated when I don't answer. Be reasonable with this though, people are very variable in how much they want to share about their lives and hear about your life. It's probably better to leave it at "I'm going to the doctor" instead of going into detail on your nasty rash. + + +## Progress +Communicating your progress ensures that both you (and your boss) know where you are. This is important to keep the project managers happy, and they in turn keep the stakeholders happy (well, at least informed if not actually happy). Communicating your progress can also make you feel good. Especially milestones; it's worth giving your colleagues and yourself a pat on the back when you hit some significant point in a project. + + +## Downsides & Difficulties +This style of communicating is not a panacea, and there may be significant downsides. For example: your boss might decide to fire you for taking off for an hour a week to look after your grandma's cat. If you had kept quiet, you would have kept your job. Although this example is facetious, it's easy to imagine situations where exposed misalignment causes more friction than simply not communicating. + +Some people find it uncomfortable to communicate openly about things they are struggling with, because they fear being seen as incompetent. This is a valid concern. + +In both of these examples, I think the problem is the environment, rather than the communication style. Open communication makes you vulnerable, so if your environment is hostile rather than supportive then you will suffer for it. + +## Conclusions +I am fortunate enough to work in a very supportive environment, so I try to communicate openly and publicly for all the benefits listed above. So far this is working well. + +Disclaimer - absolutely none of this is scientific. I have no measurements or data to back up what I'm saying here, and I have not even gone looking for existing literature on the subject. These are intuitions that I have built up from working in 2 quite different software companies for ~ 14 years. Take any advice with a big grain of salt. \ No newline at end of file diff --git a/content/posts/2024-03-03-catb.md b/content/posts/2024-03-03-catb.md deleted file mode 100644 index d620492..0000000 --- a/content/posts/2024-03-03-catb.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -.title = "Book - The Cathedral and the Bazaar", -.author = "Martin Ashby", -.date = @date("2024-03-03T19:31:27Z"), -.layout = "single.shtml", -.custom = {"comments": true}, -.description = "Book review 'The Cathedral and the Bazaar'" ---- - -I recently read [The Cathedral and the Bazaar](https://www.catb.org/~esr/writings/cathedral-bazaar/) by Eric S Raymond. - -It's interesting to get a glimpse into the early history of arguably the most successful open-source software project there has ever been. - -It's also dated somewhat. The author argues that open-source models of software development will overtake closed-source. It's clear today that open-source software has made enormous progress. Linux is more popular than ever. However there remains an _enormous_ amount of closed-source software in the world 25 years later, much of it needlessly so. There is also just an enormous amount of software in general; I'm not sure if Eric in the late 1990s and early 2000s would have predicted just how _central_ the software industry was to become in today's society and how much impact it would have. - -I think the web took off in a way that the author may not have predicted. The other conspicuously absent topic is mobile. Combined I think these have significantly changed how most people consume software, and also how most people buy software. I think the author was correct that a lot of software would change to a subscription model; perhaps what he didn't anticipate is the prevelance of end-users directly making those subscriptions for software for their phones via app stores run by gatekeepers - the latest giant software corporations. \ No newline at end of file diff --git a/content/posts/2024-03-03-catb.smd b/content/posts/2024-03-03-catb.smd new file mode 100644 index 0000000..d620492 --- /dev/null +++ b/content/posts/2024-03-03-catb.smd @@ -0,0 +1,16 @@ +--- +.title = "Book - The Cathedral and the Bazaar", +.author = "Martin Ashby", +.date = @date("2024-03-03T19:31:27Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +.description = "Book review 'The Cathedral and the Bazaar'" +--- + +I recently read [The Cathedral and the Bazaar](https://www.catb.org/~esr/writings/cathedral-bazaar/) by Eric S Raymond. + +It's interesting to get a glimpse into the early history of arguably the most successful open-source software project there has ever been. + +It's also dated somewhat. The author argues that open-source models of software development will overtake closed-source. It's clear today that open-source software has made enormous progress. Linux is more popular than ever. However there remains an _enormous_ amount of closed-source software in the world 25 years later, much of it needlessly so. There is also just an enormous amount of software in general; I'm not sure if Eric in the late 1990s and early 2000s would have predicted just how _central_ the software industry was to become in today's society and how much impact it would have. + +I think the web took off in a way that the author may not have predicted. The other conspicuously absent topic is mobile. Combined I think these have significantly changed how most people consume software, and also how most people buy software. I think the author was correct that a lot of software would change to a subscription model; perhaps what he didn't anticipate is the prevelance of end-users directly making those subscriptions for software for their phones via app stores run by gatekeepers - the latest giant software corporations. \ No newline at end of file diff --git a/content/posts/2024-03-27-zine.md b/content/posts/2024-03-27-zine.md deleted file mode 100644 index 0bfd4bf..0000000 --- a/content/posts/2024-03-27-zine.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -.title = "Zine", -.author = "Martin Ashby", -.description = "I converted my blog from [hugo](https://gohugo.io/) to [zine](https://zine-ssg.io/).", -.date = @date("2024-03-27T20:26:45+00:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I converted my blog from [hugo](https://gohugo.io/) to [zine](https://zine-ssg.io/). Hugo has been pretty good, but it had a couple of small annoyances like simple inclusion of raw HTML being difficult. Mostly though, I wanted to try something new, and my personal site is a safe space for me to do that :) - -Zine is very new, in fact the disclaimer on the site "Zine is alpha software. Using Zine today means participating in its development." turned out to be true, and I had to submit a couple of changes to Zine to make it work for me. Thankfully the maintainer was really helpful, and they also pointed out how I could generate an RSS XML feed for my blog just like hugo did. - -Code for my website can be found [here](https://code.mfashby.net/mfashby.net/). Since I have a quite a few posts, I wrote a [little program](https://code.mfashby.net/mfashby.net/tree/converter/src/main.zig) to convert the frontmatter for all my pages from hugo's YAML format to zine's ziggy format; although the output still needed some manual tweaks afterwards. - -Tangentially related, I moved the couple of videos I was hosting directly from my site to [move IT Tube](https://tube.spdns.org/) to save bandwidth at home and so others can view them faster. \ No newline at end of file diff --git a/content/posts/2024-03-27-zine.smd b/content/posts/2024-03-27-zine.smd new file mode 100644 index 0000000..0bfd4bf --- /dev/null +++ b/content/posts/2024-03-27-zine.smd @@ -0,0 +1,16 @@ +--- +.title = "Zine", +.author = "Martin Ashby", +.description = "I converted my blog from [hugo](https://gohugo.io/) to [zine](https://zine-ssg.io/).", +.date = @date("2024-03-27T20:26:45+00:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I converted my blog from [hugo](https://gohugo.io/) to [zine](https://zine-ssg.io/). Hugo has been pretty good, but it had a couple of small annoyances like simple inclusion of raw HTML being difficult. Mostly though, I wanted to try something new, and my personal site is a safe space for me to do that :) + +Zine is very new, in fact the disclaimer on the site "Zine is alpha software. Using Zine today means participating in its development." turned out to be true, and I had to submit a couple of changes to Zine to make it work for me. Thankfully the maintainer was really helpful, and they also pointed out how I could generate an RSS XML feed for my blog just like hugo did. + +Code for my website can be found [here](https://code.mfashby.net/mfashby.net/). Since I have a quite a few posts, I wrote a [little program](https://code.mfashby.net/mfashby.net/tree/converter/src/main.zig) to convert the frontmatter for all my pages from hugo's YAML format to zine's ziggy format; although the output still needed some manual tweaks afterwards. + +Tangentially related, I moved the couple of videos I was hosting directly from my site to [move IT Tube](https://tube.spdns.org/) to save bandwidth at home and so others can view them faster. \ No newline at end of file diff --git a/content/posts/2024-03-31-stranger-times.md b/content/posts/2024-03-31-stranger-times.md deleted file mode 100644 index a440e28..0000000 --- a/content/posts/2024-03-31-stranger-times.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -.title = "Book - The Stranger Times", -.author = "Martin Ashby", -.description = "I read [The Stranger Times](https://thestrangertimes.co.uk/) series by Caimh McDonnell, TL; DR they're great.", -.date = @date("2024-03-31T20:29:31+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I've read [The Stranger Times](https://thestrangertimes.co.uk/) series by Caimh McDonnell. It's a humourous but thrilling dark-fantasy series set in Manchester, centered around a newspaper featuring the weird and unexplained. It's reminiscent of 'Good Omens', the collaboration between Terry Pratchett and Neil Gaiman in both it's style and setting, particularly the fantastical world interspersed with the ordinary and yet invisible to most. - -I can't wait to read the 5th and 6th books of the series which have [already been commissioned](https://www.chortle.co.uk/news/2023/10/03/54271/caimh_mcdonnell_signs_up_to_three_more_stranger_times_novels). \ No newline at end of file diff --git a/content/posts/2024-03-31-stranger-times.smd b/content/posts/2024-03-31-stranger-times.smd new file mode 100644 index 0000000..a440e28 --- /dev/null +++ b/content/posts/2024-03-31-stranger-times.smd @@ -0,0 +1,12 @@ +--- +.title = "Book - The Stranger Times", +.author = "Martin Ashby", +.description = "I read [The Stranger Times](https://thestrangertimes.co.uk/) series by Caimh McDonnell, TL; DR they're great.", +.date = @date("2024-03-31T20:29:31+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I've read [The Stranger Times](https://thestrangertimes.co.uk/) series by Caimh McDonnell. It's a humourous but thrilling dark-fantasy series set in Manchester, centered around a newspaper featuring the weird and unexplained. It's reminiscent of 'Good Omens', the collaboration between Terry Pratchett and Neil Gaiman in both it's style and setting, particularly the fantastical world interspersed with the ordinary and yet invisible to most. + +I can't wait to read the 5th and 6th books of the series which have [already been commissioned](https://www.chortle.co.uk/news/2023/10/03/54271/caimh_mcdonnell_signs_up_to_three_more_stranger_times_novels). \ No newline at end of file diff --git a/content/posts/2024-05-23-zigvm.md b/content/posts/2024-05-23-zigvm.md deleted file mode 100644 index c395dca..0000000 --- a/content/posts/2024-05-23-zigvm.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -.title = "zigvm", -.author = "Martin Ashby", -.date = @date("2024-05-23T22:24:34+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I wrote a tool to download and manage Zig versions ... in zig. - -It uses the [JSON](https://ziglang.org/download/index.json) metadata available for zig downloads. It has one third party dependency on [minisign](https://github.com/jedisct1/zig-minisign). JSON parsing, HTTPS client, and tar/compression were all available in the standard library. - -[Project page](/projects/zigvm) \ No newline at end of file diff --git a/content/posts/2024-05-23-zigvm.smd b/content/posts/2024-05-23-zigvm.smd new file mode 100644 index 0000000..c395dca --- /dev/null +++ b/content/posts/2024-05-23-zigvm.smd @@ -0,0 +1,13 @@ +--- +.title = "zigvm", +.author = "Martin Ashby", +.date = @date("2024-05-23T22:24:34+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I wrote a tool to download and manage Zig versions ... in zig. + +It uses the [JSON](https://ziglang.org/download/index.json) metadata available for zig downloads. It has one third party dependency on [minisign](https://github.com/jedisct1/zig-minisign). JSON parsing, HTTPS client, and tar/compression were all available in the standard library. + +[Project page](/projects/zigvm) \ No newline at end of file diff --git a/content/posts/2024-08-09-bike.md b/content/posts/2024-08-09-bike.md deleted file mode 100644 index 317d624..0000000 --- a/content/posts/2024-08-09-bike.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -.title = "Bike 4", -.author = "Martin Ashby", -.description = "I got a cargo bike, it's fab", -.date = @date("2024-08-09T14:11:48+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I recently purchased a [Tern GSD](https://www.ternbicycles.com/uk/bikes/472/gsd) electric cargo bike. I have somewhat wanted an e-cargo bike since I saw one nearby a couple of years ago. Lately, circumstances have made it a good choice for me. - -![Tern front view](front.webp) - -As a family we only have one car, with no room or budget for a second. My wife uses the car to commute to work, and my kids are growing up and want to travel to activities further away than the local park. Our public transport is not very reliable, and not in a the right direction or times for us. The bike is a convenient way to travel a few miles. It offers some of the convenience of a car; such as a large carrying capacity, and we can travel on our own schedule rather than racing for a bus, but without some of the downsides like requiring an extra parking space. - -There are some downsides; there has already been one attempted theft of the bike. I've spent a lot on a couple of high security locks and some specialised e-bike insurance to mitigate this, but it remains a concern. I've also taken one pretty bad fall; luckily with no cargo or passengers. I need to consciously adapt my riding style for the larger heavier ride, and I'm still getting used to this. Finally; I've not yet attempted a journey more than around 5 miles with the children aboard. For longer distances, the additional travel time does mean extra planning. I also prefer to take off-road routes, especially with the children, to reduce the risk of traffic collision. - -Overall I would recommend the bike if you are a confident cyclist, or if you are not confident but live somewhere with great cycling infrastructure. My kids prefer to ride on the bike rather than in the car, they think it's more fun. And I agree with them! - -![Woman riding tern GSD](georgia.webp) - -![Tern GSD bike loaded with shopping](loaded.webp) - -![Tern GSD bike without storm box](nobox.webp) - -My old bike is not left out. I still use it regularly when I don't need to carry kids or cargo. It got a re-colour and a new front rack and kick-stand as well. - -![Orange and pink hybrid bike](gravel.webp) - diff --git a/content/posts/2024-08-09-bike.smd b/content/posts/2024-08-09-bike.smd new file mode 100644 index 0000000..317d624 --- /dev/null +++ b/content/posts/2024-08-09-bike.smd @@ -0,0 +1,29 @@ +--- +.title = "Bike 4", +.author = "Martin Ashby", +.description = "I got a cargo bike, it's fab", +.date = @date("2024-08-09T14:11:48+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I recently purchased a [Tern GSD](https://www.ternbicycles.com/uk/bikes/472/gsd) electric cargo bike. I have somewhat wanted an e-cargo bike since I saw one nearby a couple of years ago. Lately, circumstances have made it a good choice for me. + +![Tern front view](front.webp) + +As a family we only have one car, with no room or budget for a second. My wife uses the car to commute to work, and my kids are growing up and want to travel to activities further away than the local park. Our public transport is not very reliable, and not in a the right direction or times for us. The bike is a convenient way to travel a few miles. It offers some of the convenience of a car; such as a large carrying capacity, and we can travel on our own schedule rather than racing for a bus, but without some of the downsides like requiring an extra parking space. + +There are some downsides; there has already been one attempted theft of the bike. I've spent a lot on a couple of high security locks and some specialised e-bike insurance to mitigate this, but it remains a concern. I've also taken one pretty bad fall; luckily with no cargo or passengers. I need to consciously adapt my riding style for the larger heavier ride, and I'm still getting used to this. Finally; I've not yet attempted a journey more than around 5 miles with the children aboard. For longer distances, the additional travel time does mean extra planning. I also prefer to take off-road routes, especially with the children, to reduce the risk of traffic collision. + +Overall I would recommend the bike if you are a confident cyclist, or if you are not confident but live somewhere with great cycling infrastructure. My kids prefer to ride on the bike rather than in the car, they think it's more fun. And I agree with them! + +![Woman riding tern GSD](georgia.webp) + +![Tern GSD bike loaded with shopping](loaded.webp) + +![Tern GSD bike without storm box](nobox.webp) + +My old bike is not left out. I still use it regularly when I don't need to carry kids or cargo. It got a re-colour and a new front rack and kick-stand as well. + +![Orange and pink hybrid bike](gravel.webp) + diff --git a/content/posts/2024-08-23-book-meltdown.md b/content/posts/2024-08-23-book-meltdown.md deleted file mode 100644 index c53f489..0000000 --- a/content/posts/2024-08-23-book-meltdown.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -.title = "Book - Meltdown: Why Our Systems Fail and What We Can Do About It", -.author = "Martin Ashby", -.description = "Short review of Meltdown: Why Our Systems Fail and What We Can Do About It", -.date = @date("2024-08-23T22:04:46+01:00"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I recently read [Meltdown: Why Our Systems Fail and What We Can Do About It, by Chris Clearfield and András Tilcsik](https://www.goodreads.com/book/show/35629742-meltdown). - -I think this book is super-relevant to anyone working with IT systems. The theme of many meltdowns examined here is 'Complexity and tight coupling'. I think that computer software is the pinnacle of human-made complexity. It is built upon layers and layers of abstractions and subsystems, and relies on equally complex hardware. It is built on decades of intense iterative improvement with an enormous amount of research and development. It is now well beyond the point where any single person can have an understanding of all parts of a modern computer. - -We are seeing more meltdowns in IT over time. I'm curious to find out if this trend will continue or if we will find ways to handle and tame the complexity. \ No newline at end of file diff --git a/content/posts/2024-08-23-book-meltdown.smd b/content/posts/2024-08-23-book-meltdown.smd new file mode 100644 index 0000000..c53f489 --- /dev/null +++ b/content/posts/2024-08-23-book-meltdown.smd @@ -0,0 +1,14 @@ +--- +.title = "Book - Meltdown: Why Our Systems Fail and What We Can Do About It", +.author = "Martin Ashby", +.description = "Short review of Meltdown: Why Our Systems Fail and What We Can Do About It", +.date = @date("2024-08-23T22:04:46+01:00"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I recently read [Meltdown: Why Our Systems Fail and What We Can Do About It, by Chris Clearfield and András Tilcsik](https://www.goodreads.com/book/show/35629742-meltdown). + +I think this book is super-relevant to anyone working with IT systems. The theme of many meltdowns examined here is 'Complexity and tight coupling'. I think that computer software is the pinnacle of human-made complexity. It is built upon layers and layers of abstractions and subsystems, and relies on equally complex hardware. It is built on decades of intense iterative improvement with an enormous amount of research and development. It is now well beyond the point where any single person can have an understanding of all parts of a modern computer. + +We are seeing more meltdowns in IT over time. I'm curious to find out if this trend will continue or if we will find ways to handle and tame the complexity. \ No newline at end of file diff --git a/content/posts/2024-08-24-wyag.md b/content/posts/2024-08-24-wyag.md deleted file mode 100644 index e69e0cb..0000000 --- a/content/posts/2024-08-24-wyag.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -.title = "Write Yourself A Git", -.author = "Martin Ashby", -.date = @date("2024-08-24T12:22:20+01:00"), -.description = "I've been working through 'Write youself a git'", -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I didn't understand how git really worked, and I was curious. Since I also have to work with git every day, it seemed sensible to learn a bit more about how it works. I'm not a particularly advanced git user; I mostly stick to the basic commands 'checkout', 'merge', 'pull' and 'push', and occasionally 'rebase'. - -I bought [How Git Works](https://store.wizardzines.com/products/how-git-works) from Julia Evans. This is a great introduction to how git works; it's very accessible to me and I like Julia's writing style. - -I prefer to explore and experience, rather than simply read about a subject, so I was happy to find [Write Yourself A Git](https://wyag.thb.lt/). I've been [working through it in zig](https://code.mfashby.net/wyag/files.html). diff --git a/content/posts/2024-08-24-wyag.smd b/content/posts/2024-08-24-wyag.smd new file mode 100644 index 0000000..e69e0cb --- /dev/null +++ b/content/posts/2024-08-24-wyag.smd @@ -0,0 +1,14 @@ +--- +.title = "Write Yourself A Git", +.author = "Martin Ashby", +.date = @date("2024-08-24T12:22:20+01:00"), +.description = "I've been working through 'Write youself a git'", +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I didn't understand how git really worked, and I was curious. Since I also have to work with git every day, it seemed sensible to learn a bit more about how it works. I'm not a particularly advanced git user; I mostly stick to the basic commands 'checkout', 'merge', 'pull' and 'push', and occasionally 'rebase'. + +I bought [How Git Works](https://store.wizardzines.com/products/how-git-works) from Julia Evans. This is a great introduction to how git works; it's very accessible to me and I like Julia's writing style. + +I prefer to explore and experience, rather than simply read about a subject, so I was happy to find [Write Yourself A Git](https://wyag.thb.lt/). I've been [working through it in zig](https://code.mfashby.net/wyag/files.html). diff --git a/content/posts/2024-12-01-aoc2024.md b/content/posts/2024-12-01-aoc2024.md deleted file mode 100644 index 79e400b..0000000 --- a/content/posts/2024-12-01-aoc2024.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -.title = "Advent of Code 2024", -.author = "Martin Ashby", -.date = @date("2024-12-01T22:11:35Z"), -.layout = "single.shtml", -.custom = {"comments": true}, ---- - -I'm doing [Advent of Code](https://adventofcode.com/) again, in [Scala](https://scala-lang.org/) this year. - -I'm probably not going to get very far with this year, as I don't have a ton of free time right now. However it still interests me enough to have a go at the first few days. - -[code](https://code.mfashby.net/aoc2024/) \ No newline at end of file diff --git a/content/posts/2024-12-01-aoc2024.smd b/content/posts/2024-12-01-aoc2024.smd new file mode 100644 index 0000000..79e400b --- /dev/null +++ b/content/posts/2024-12-01-aoc2024.smd @@ -0,0 +1,13 @@ +--- +.title = "Advent of Code 2024", +.author = "Martin Ashby", +.date = @date("2024-12-01T22:11:35Z"), +.layout = "single.shtml", +.custom = {"comments": true}, +--- + +I'm doing [Advent of Code](https://adventofcode.com/) again, in [Scala](https://scala-lang.org/) this year. + +I'm probably not going to get very far with this year, as I don't have a ton of free time right now. However it still interests me enough to have a go at the first few days. + +[code](https://code.mfashby.net/aoc2024/) \ No newline at end of file diff --git a/content/posts/index.md b/content/posts/index.md deleted file mode 100644 index eb0b90b..0000000 --- a/content/posts/index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -.title = "mfashby.net", -.author = "Martin Ashby", -.date = @date("1900-01-01T00:00:00Z"), -.layout = "list.shtml", -.alternatives = [{ - .layout = "rss.xml", - .output = "index.xml", -}], ---- diff --git a/content/posts/index.smd b/content/posts/index.smd new file mode 100644 index 0000000..922463b --- /dev/null +++ b/content/posts/index.smd @@ -0,0 +1,12 @@ +--- +.title = "mfashby.net", +.author = "Martin Ashby", +.date = @date("1900-01-01T00:00:00Z"), +.layout = "list.shtml", +.alternatives = [{ + .name = "rss", + .type = "application/rss+xml", + .layout = "rss.xml", + .output = "index.xml", +}], +--- diff --git a/content/projects/index.md b/content/projects/index.md deleted file mode 100644 index 1c70c79..0000000 --- a/content/projects/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -.title = "About", -.author = "Martin Ashby", -.date = @date("2024-03-01T23:59:52Z"), -.layout = "list.shtml", ---- diff --git a/content/projects/index.smd b/content/projects/index.smd new file mode 100644 index 0000000..1c70c79 --- /dev/null +++ b/content/projects/index.smd @@ -0,0 +1,6 @@ +--- +.title = "About", +.author = "Martin Ashby", +.date = @date("2024-03-01T23:59:52Z"), +.layout = "list.shtml", +--- diff --git a/content/projects/zigvm.md b/content/projects/zigvm.md deleted file mode 100644 index c19fbd3..0000000 --- a/content/projects/zigvm.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -.title = "zigvm", -.author = "Martin Ashby", -.date = @date("2024-05-28T20:18:54+01:00"), -.layout = "single.shtml", ---- - -A tool to download and manage versions of the [zig](https://ziglang.org/) compiler. - -## Why? - -* I got fed up of installing manually -* I like to practice programming by writing small tools - -## Why not AUR/nix/apt/X? - -None of those were quite as convenient as what I wanted, they come with other baggage, and they don't always ship the latest bleeding-edge zig version. - -## How to use - -Run `zigvm` with no arguments to download the latest `master` version of zig and install/symlink in `~/.local.bin`. Run `zigvm -h` to see options. - -## Downloads - -* [Code](https://code.mfashby.net/zigvm/) -* [aarch64-linux](https://dl.mfashby.net/zigvm/v0.2.0/aarch64-linux) [SHA256 checksum](https://dl.mfashby.net/zigvm/v0.2.0/aarch64-linux.sha256) [minisig](https://dl.mfashby.net/zigvm/v0.2.0/aarch64-linux.minisig) -* [x86_64-linux](https://dl.mfashby.net/zigvm/v0.2.0/x86_64-linux) [SHA256 checksum](https://dl.mfashby.net/zigvm/v0.2.0/x86_64-linux.sha256) [minisig](https://dl.mfashby.net/zigvm/v0.2.0/x86_64-linux.minisig) - -Binaries are signed with [minisign](https://jedisct1.github.io/minisign/), public key `RWTsE4a/BXFWjmzxWB0Kko+w47ZRfQhxkF21Zfh7BxRzZm2q6l4GssRa` - -## Release notes \ No newline at end of file diff --git a/content/projects/zigvm.smd b/content/projects/zigvm.smd new file mode 100644 index 0000000..c19fbd3 --- /dev/null +++ b/content/projects/zigvm.smd @@ -0,0 +1,31 @@ +--- +.title = "zigvm", +.author = "Martin Ashby", +.date = @date("2024-05-28T20:18:54+01:00"), +.layout = "single.shtml", +--- + +A tool to download and manage versions of the [zig](https://ziglang.org/) compiler. + +## Why? + +* I got fed up of installing manually +* I like to practice programming by writing small tools + +## Why not AUR/nix/apt/X? + +None of those were quite as convenient as what I wanted, they come with other baggage, and they don't always ship the latest bleeding-edge zig version. + +## How to use + +Run `zigvm` with no arguments to download the latest `master` version of zig and install/symlink in `~/.local.bin`. Run `zigvm -h` to see options. + +## Downloads + +* [Code](https://code.mfashby.net/zigvm/) +* [aarch64-linux](https://dl.mfashby.net/zigvm/v0.2.0/aarch64-linux) [SHA256 checksum](https://dl.mfashby.net/zigvm/v0.2.0/aarch64-linux.sha256) [minisig](https://dl.mfashby.net/zigvm/v0.2.0/aarch64-linux.minisig) +* [x86_64-linux](https://dl.mfashby.net/zigvm/v0.2.0/x86_64-linux) [SHA256 checksum](https://dl.mfashby.net/zigvm/v0.2.0/x86_64-linux.sha256) [minisig](https://dl.mfashby.net/zigvm/v0.2.0/x86_64-linux.minisig) + +Binaries are signed with [minisign](https://jedisct1.github.io/minisign/), public key `RWTsE4a/BXFWjmzxWB0Kko+w47ZRfQhxkF21Zfh7BxRzZm2q6l4GssRa` + +## Release notes \ No newline at end of file diff --git a/content/projects/zipdl.md b/content/projects/zipdl.md deleted file mode 100644 index 0ef7bc6..0000000 --- a/content/projects/zipdl.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -.title = "zipdl", -.author = "Martin Ashby", -.date = @date("2024-05-28T20:18:54+01:00"), -.layout = "single.shtml", ---- - -A program for downloading individual files from a remote ZIP file on a http server that supports [Range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range) requests. - -## why? -This was an interesting learning exercise. - -## Download - -Binary releases: -* [linux aarch64](https://dl.mfashby.net/zipdl/0.0.1/aarch64-linux-gnu/zipdl.xz) [checksum](https://dl.mfashby.net/zipdl/0.0.1/aarch64-linux-gnu/zipdl.xz.sha256) -* [linux x86_64](https://dl.mfashby.net/zipdl/0.0.1/x86_64-linux-gnu/zipdl.xz) [checksum](https://dl.mfashby.net/zipdl/0.0.1/x86_64-linux-gnu/zipdl.xz.sha256) - -Download the appropriate file for your platform and the checksum, then check and extract: -``` -sha256sum -c zipdl.xz.sha256 -# result MUST be zipdl.xz: OK - -unxz zipdl.xz -``` -and run with -h for help -``` -./zipdl -h -``` - -To build from source, download the code, download [zig](https://ziglang.org/download/), and run `zig build` to produce a binary in zig-out/bin folder. diff --git a/content/projects/zipdl.smd b/content/projects/zipdl.smd new file mode 100644 index 0000000..0ef7bc6 --- /dev/null +++ b/content/projects/zipdl.smd @@ -0,0 +1,31 @@ +--- +.title = "zipdl", +.author = "Martin Ashby", +.date = @date("2024-05-28T20:18:54+01:00"), +.layout = "single.shtml", +--- + +A program for downloading individual files from a remote ZIP file on a http server that supports [Range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range) requests. + +## why? +This was an interesting learning exercise. + +## Download + +Binary releases: +* [linux aarch64](https://dl.mfashby.net/zipdl/0.0.1/aarch64-linux-gnu/zipdl.xz) [checksum](https://dl.mfashby.net/zipdl/0.0.1/aarch64-linux-gnu/zipdl.xz.sha256) +* [linux x86_64](https://dl.mfashby.net/zipdl/0.0.1/x86_64-linux-gnu/zipdl.xz) [checksum](https://dl.mfashby.net/zipdl/0.0.1/x86_64-linux-gnu/zipdl.xz.sha256) + +Download the appropriate file for your platform and the checksum, then check and extract: +``` +sha256sum -c zipdl.xz.sha256 +# result MUST be zipdl.xz: OK + +unxz zipdl.xz +``` +and run with -h for help +``` +./zipdl -h +``` + +To build from source, download the code, download [zig](https://ziglang.org/download/), and run `zig build` to produce a binary in zig-out/bin folder. -- cgit v1.2.3-ZIG