From 6f3729b383909ca091925defed83d8ce37b9e7d5 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 7 Mar 2021 16:23:59 -0800 Subject: initial site with hugo Start my website from scratch once more, using hugo to generate it. For now the layout is pretty simple: - an index page that will list future notes - notes should be created under the "content" directory The theme is custom and I'll try to keep this simple. --- users/fcuny/blog/.gitignore | 1 + users/fcuny/blog/archetypes/default.md | 5 +++ users/fcuny/blog/config.toml | 35 ++++++++++++++++++++ users/fcuny/blog/layouts/_default/baseof.html | 11 +++++++ users/fcuny/blog/layouts/_default/list.html | 10 ++++++ users/fcuny/blog/layouts/_default/single.html | 11 +++++++ users/fcuny/blog/layouts/index.atom.xml | 22 +++++++++++++ users/fcuny/blog/layouts/index.html | 22 +++++++++++++ users/fcuny/blog/layouts/partials/head.html | 15 +++++++++ users/fcuny/blog/static/CNAME | 1 + users/fcuny/blog/static/css/custom.css | 47 +++++++++++++++++++++++++++ 11 files changed, 180 insertions(+) create mode 100644 users/fcuny/blog/.gitignore create mode 100644 users/fcuny/blog/archetypes/default.md create mode 100644 users/fcuny/blog/config.toml create mode 100644 users/fcuny/blog/layouts/_default/baseof.html create mode 100644 users/fcuny/blog/layouts/_default/list.html create mode 100644 users/fcuny/blog/layouts/_default/single.html create mode 100644 users/fcuny/blog/layouts/index.atom.xml create mode 100644 users/fcuny/blog/layouts/index.html create mode 100644 users/fcuny/blog/layouts/partials/head.html create mode 100644 users/fcuny/blog/static/CNAME create mode 100644 users/fcuny/blog/static/css/custom.css (limited to 'users/fcuny') diff --git a/users/fcuny/blog/.gitignore b/users/fcuny/blog/.gitignore new file mode 100644 index 0000000..6e68499 --- /dev/null +++ b/users/fcuny/blog/.gitignore @@ -0,0 +1 @@ +/docs/ diff --git a/users/fcuny/blog/archetypes/default.md b/users/fcuny/blog/archetypes/default.md new file mode 100644 index 0000000..7ce2f1a --- /dev/null +++ b/users/fcuny/blog/archetypes/default.md @@ -0,0 +1,5 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +date: {{ .Date }} +--- + diff --git a/users/fcuny/blog/config.toml b/users/fcuny/blog/config.toml new file mode 100644 index 0000000..44080ae --- /dev/null +++ b/users/fcuny/blog/config.toml @@ -0,0 +1,35 @@ +baseURL = "http://fcuny.net/" +languageCode = "en-us" +title = "Franck Cuny's Website" +publishDir = "docs" + +[params] + homeText = "A collection of articles" + +[permalinks] + articles = "/:section/:slug/" + +[markup] + [markup.highlight] + anchorLineNos = false + codeFences = true + guessSyntax = false + hl_Lines = "" + lineAnchors = "" + lineNoStart = 1 + lineNos = false + lineNumbersInTable = true + noClasses = true + style = "emacs" + tabWidth = 2 + +[mediaTypes."application/atom"] +suffixes = ["xml"] + +[outputFormats.Atom] +mediaType = "application/atom" +baseName = "feed" +isPlainText = false + +[outputs] +home = [ "HTML", "Atom" ] diff --git a/users/fcuny/blog/layouts/_default/baseof.html b/users/fcuny/blog/layouts/_default/baseof.html new file mode 100644 index 0000000..d9ca51a --- /dev/null +++ b/users/fcuny/blog/layouts/_default/baseof.html @@ -0,0 +1,11 @@ + + + {{ partial "head.html" . }} + +
+
+ {{ block "main" . }}{{ end }} +
+
+ + diff --git a/users/fcuny/blog/layouts/_default/list.html b/users/fcuny/blog/layouts/_default/list.html new file mode 100644 index 0000000..3423cb6 --- /dev/null +++ b/users/fcuny/blog/layouts/_default/list.html @@ -0,0 +1,10 @@ +{{ define "main" }} + +

{{ .Title }}

+{{ range .Pages.ByPublishDate.Reverse }} +

+ {{ .Title }} +

+{{ end }} + +{{ end }} diff --git a/users/fcuny/blog/layouts/_default/single.html b/users/fcuny/blog/layouts/_default/single.html new file mode 100644 index 0000000..a8c1dc7 --- /dev/null +++ b/users/fcuny/blog/layouts/_default/single.html @@ -0,0 +1,11 @@ +{{ define "main" }} + +

← Back to Franck's homepage

+ +

{{ .Title }}

+ +

{{ .Date.Format "January 2021" }}

+ +{{ .Content }} + +{{ end }} diff --git a/users/fcuny/blog/layouts/index.atom.xml b/users/fcuny/blog/layouts/index.atom.xml new file mode 100644 index 0000000..531e77c --- /dev/null +++ b/users/fcuny/blog/layouts/index.atom.xml @@ -0,0 +1,22 @@ + + Franck Cuny Website + + + {{ .Permalink }}{{ with .Site.Author.name }} + + {{.}}{{ with $.Site.Author.email }} + {{.}}{{end}} + {{end}} + Hugo -- gohugo.io{{ range where (first 10 (where .Site.Pages "Section" "posts")) "Params.hidden" "ne" "true" }} + + {{ `<![CDATA[` | safeHTML }}{{ .Title }}]]> + + {{ .Permalink }}{{ with .Site.Params.Author }} + + {{.}} + {{end}} + {{- $fmt := "2006-01-02T15:04:05-07:00" }} + {{ .Date.Format $fmt | safeHTML }} + {{ ` + {{ end }} + diff --git a/users/fcuny/blog/layouts/index.html b/users/fcuny/blog/layouts/index.html new file mode 100644 index 0000000..5f49f24 --- /dev/null +++ b/users/fcuny/blog/layouts/index.html @@ -0,0 +1,22 @@ +{{ define "main" }} + +
+

Franck Cuny

+ + + +

I'm currently working as a Site Reliability Engineer at Twitter, on the Compute team.

+ +

Notes

+ {{ $section := "notes" }} + + +{{ end }} diff --git a/users/fcuny/blog/layouts/partials/head.html b/users/fcuny/blog/layouts/partials/head.html new file mode 100644 index 0000000..9301a82 --- /dev/null +++ b/users/fcuny/blog/layouts/partials/head.html @@ -0,0 +1,15 @@ + + + + + + + {{ $css := "/css/custom.css" }} + + + + + + + {{ .Title }} + diff --git a/users/fcuny/blog/static/CNAME b/users/fcuny/blog/static/CNAME new file mode 100644 index 0000000..7398ba2 --- /dev/null +++ b/users/fcuny/blog/static/CNAME @@ -0,0 +1 @@ +fcuny.net \ No newline at end of file diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css new file mode 100644 index 0000000..45f9732 --- /dev/null +++ b/users/fcuny/blog/static/css/custom.css @@ -0,0 +1,47 @@ +@import url('https://fonts.googleapis.com/css?family=Roboto+Slab:400,700'); +@import url('https://fonts.googleapis.com/css?family=Roboto+Mono:400'); + +*, *:before, *:after { box-sizing: border-box; } + +body { + background-color: #ffffea; + line-height: 1.6rem; + font-size: 18px; + font-family: "Roboto Slab", serif; + color: #000; + padding: 2rem; +} + +.main { + margin: auto; + max-width: 50rem; +} + +a { + text-decoration: none; + color: #00add8; +} + +p { color: #1a1a19; } + +h1 { + line-height: normal; +} + +h2 { + margin-top: 2rem; + line-height: 1.4em; +} + +span.published, span.updated { + display: block; + font-style: oblique; +} + +pre { + padding: 1rem 2rem; + margin: 0; + font-size: 16px; + font-family: "Roboto Mono", Monaco, "Lucida Console", monospace; + overflow: scroll; +} -- cgit 1.4.1 From 2c06ba852641ca1c94e3a3dd33039ff6b96ab1c5 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 7 Mar 2021 16:47:23 -0800 Subject: add action to publish to GH pages Add a workflow configuration to publish to GitHub pages. This is using the standard configuration from https://gohugo.io/hosting-and-deployment/hosting-on-github/ --- users/fcuny/blog/.github/workflows/gh-pages.yml | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 users/fcuny/blog/.github/workflows/gh-pages.yml (limited to 'users/fcuny') diff --git a/users/fcuny/blog/.github/workflows/gh-pages.yml b/users/fcuny/blog/.github/workflows/gh-pages.yml new file mode 100644 index 0000000..70e9ca8 --- /dev/null +++ b/users/fcuny/blog/.github/workflows/gh-pages.yml @@ -0,0 +1,30 @@ +name: github pages + +on: + push: + branches: + - main # Set a branch to deploy + +jobs: + deploy: + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: true # Fetch Hugo themes (true OR recursive) + fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod + + - name: Setup Hugo + uses: peaceiris/actions-hugo@v2 + with: + hugo-version: 'latest' + # extended: true + + - name: Build + run: hugo --minify + + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./docs -- cgit 1.4.1 From eb63f1ec9de3e6c4d14d447422c4a05faa11c0be Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 6 Apr 2021 12:28:27 -0700 Subject: layout: clean up empty space --- users/fcuny/blog/layouts/partials/head.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/partials/head.html b/users/fcuny/blog/layouts/partials/head.html index 9301a82..f41eb04 100644 --- a/users/fcuny/blog/layouts/partials/head.html +++ b/users/fcuny/blog/layouts/partials/head.html @@ -7,7 +7,7 @@ {{ $css := "/css/custom.css" }} - + -- cgit 1.4.1 From a5546c7cc2d31f78c7c6fc08fa379b859245210f Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 6 Apr 2021 12:28:53 -0700 Subject: layout: fix format for the date --- users/fcuny/blog/layouts/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/index.html b/users/fcuny/blog/layouts/index.html index 5f49f24..450444b 100644 --- a/users/fcuny/blog/layouts/index.html +++ b/users/fcuny/blog/layouts/index.html @@ -15,7 +15,7 @@ {{ $section := "notes" }} -- cgit 1.4.1 From 79697d945deed96280df98c3bee4994c73e2977c Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 6 Apr 2021 12:29:45 -0700 Subject: css: change the default font --- users/fcuny/blog/static/css/custom.css | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index 45f9732..c84a013 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -1,13 +1,13 @@ -@import url('https://fonts.googleapis.com/css?family=Roboto+Slab:400,700'); +@import url('https://fonts.googleapis.com/css2?family=Roboto'); @import url('https://fonts.googleapis.com/css?family=Roboto+Mono:400'); *, *:before, *:after { box-sizing: border-box; } body { - background-color: #ffffea; - line-height: 1.6rem; - font-size: 18px; - font-family: "Roboto Slab", serif; + background-color: #ffffff; + line-height: 1.5rem; + font-size: 16px; + font-family: "Roboto", Arial, sans-serif; color: #000; padding: 2rem; } -- cgit 1.4.1 From 12d5254bde5bca032dcd4932504df7ae1709984b Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 6 Apr 2021 12:30:59 -0700 Subject: css: set background color for code block Indent properly the CSS for the `pre` tag. --- users/fcuny/blog/static/css/custom.css | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index c84a013..b3c3e2f 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -38,10 +38,14 @@ span.published, span.updated { font-style: oblique; } +code { + background-color: #eeeeee; +} + pre { - padding: 1rem 2rem; - margin: 0; - font-size: 16px; - font-family: "Roboto Mono", Monaco, "Lucida Console", monospace; - overflow: scroll; + padding: 1rem 2rem; + margin: 0; + font-size: 16px; + font-family: "Roboto Mono", Monaco, "Lucida Console", monospace; + overflow: scroll; } -- cgit 1.4.1 From f29dad7dc02a2fac22b0086ad67e1e1784913974 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 6 Apr 2021 12:31:33 -0700 Subject: css: update style for links and headers Indent properly the CSS --- users/fcuny/blog/static/css/custom.css | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index b3c3e2f..b0ec570 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -18,8 +18,9 @@ body { } a { - text-decoration: none; - color: #00add8; + text-decoration: underline; + text-underline-offset:.3rem; + color: #007d9c; } p { color: #1a1a19; } @@ -29,8 +30,11 @@ h1 { } h2 { - margin-top: 2rem; - line-height: 1.4em; + margin-top: 2rem; + line-height: 1.4em; + border-bottom-color: #000000; + border-bottom-style: solid; + border-bottom-width: 0.8px; } span.published, span.updated { -- cgit 1.4.1 From 7025d1ca1e7a42212eeb4e648176986135fd8438 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 6 Apr 2021 12:32:43 -0700 Subject: layout: add date and tags to single pages We want to show the tags and the published/updated date for the articles. Add to the CSS the classes for these new elements. --- users/fcuny/blog/layouts/_default/single.html | 27 ++++++++++++++++++++++++++- users/fcuny/blog/static/css/custom.css | 16 ++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/_default/single.html b/users/fcuny/blog/layouts/_default/single.html index a8c1dc7..0ab5e35 100644 --- a/users/fcuny/blog/layouts/_default/single.html +++ b/users/fcuny/blog/layouts/_default/single.html @@ -4,7 +4,32 @@

{{ .Title }}

-

{{ .Date.Format "January 2021" }}

+
+ {{- $pub := .Date.Format "2006-01-02" -}} + {{- $mod := "" -}} + {{- if (not .GitInfo) }} + {{- $mod = .Lastmod.Format "2006-01-02" -}} + {{ else }} + {{- $mod = .Page.GitInfo.CommitDate.Format "2006-01-02" -}} + {{ end -}} + {{ if eq $pub $mod }} +
published {{ $pub }}
+ {{ else }} +
published {{ $pub }}, last modified {{ $mod }}
+ {{ end }} + {{ if .Params.tags }} +
+ {{ if eq (len .Params.tags) 1 }} + in tag + {{ else }} + in tags + {{ end }} + {{ range $idx, $tag := .Params.tags }} + {{ $tag }} + {{ end }} +
+ {{ end }} +
{{ .Content }} diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index b0ec570..9d4faf1 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -53,3 +53,19 @@ pre { font-family: "Roboto Mono", Monaco, "Lucida Console", monospace; overflow: scroll; } + +.tags { + background-color: #eeeeee; + border-radius:8px; + padding:0 .5rem; + font-size: 90%; +} + +.meta_tags a:link, +.meta_tags a:visited { + text-decoration: none; +} + +.meta_date { + font-style: italic; +} -- cgit 1.4.1 From bebc3eb665e6223a974e5e73fe5f54b382e3891b Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 6 Apr 2021 12:33:39 -0700 Subject: taxonomy: add pages for tags We want to have pages that list all the articles related to a given tag. Update the configuration to add support for tags and the permalink structure. --- users/fcuny/blog/config.toml | 32 ++++++++++--------------- users/fcuny/blog/layouts/partials/postlist.html | 30 +++++++++++++++++++++++ users/fcuny/blog/layouts/taxonomy/tag.html | 6 +++++ 3 files changed, 48 insertions(+), 20 deletions(-) create mode 100644 users/fcuny/blog/layouts/partials/postlist.html create mode 100644 users/fcuny/blog/layouts/taxonomy/tag.html (limited to 'users/fcuny') diff --git a/users/fcuny/blog/config.toml b/users/fcuny/blog/config.toml index 44080ae..23df087 100644 --- a/users/fcuny/blog/config.toml +++ b/users/fcuny/blog/config.toml @@ -2,34 +2,26 @@ baseURL = "http://fcuny.net/" languageCode = "en-us" title = "Franck Cuny's Website" publishDir = "docs" +enableGitInfo = true +markup = "org" [params] - homeText = "A collection of articles" + homeText = "A collection of notes" + +[taxonomies] + tag = "tags" [permalinks] articles = "/:section/:slug/" - -[markup] - [markup.highlight] - anchorLineNos = false - codeFences = true - guessSyntax = false - hl_Lines = "" - lineAnchors = "" - lineNoStart = 1 - lineNos = false - lineNumbersInTable = true - noClasses = true - style = "emacs" - tabWidth = 2 + tags = "/tags/:slug/" [mediaTypes."application/atom"] -suffixes = ["xml"] + suffixes = ["xml"] [outputFormats.Atom] -mediaType = "application/atom" -baseName = "feed" -isPlainText = false + mediaType = "application/atom" + baseName = "feed" + isPlainText = false [outputs] -home = [ "HTML", "Atom" ] + home = [ "HTML", "Atom" ] diff --git a/users/fcuny/blog/layouts/partials/postlist.html b/users/fcuny/blog/layouts/partials/postlist.html new file mode 100644 index 0000000..3695d82 --- /dev/null +++ b/users/fcuny/blog/layouts/partials/postlist.html @@ -0,0 +1,30 @@ +

← Back to Franck's homepage

+ +{{ range .GroupByDate "2006-Jan" }} +

{{ .Key }}

+
    + {{ range .Pages.ByDate }} +
  • +
    +

    {{ .Title }}

    + {{ if .Params.tags }} +
    + Tags: + {{ range $idx, $tag := .Params.tags }} + {{ $tag }} + {{ end }} +
    + {{ else }} +
    + {{ end }} +
    +
    +

    + {{ .Summary }} + Read more → +

    +
    +
  • + {{ end }} +
+{{ end }} diff --git a/users/fcuny/blog/layouts/taxonomy/tag.html b/users/fcuny/blog/layouts/taxonomy/tag.html new file mode 100644 index 0000000..2b7d98a --- /dev/null +++ b/users/fcuny/blog/layouts/taxonomy/tag.html @@ -0,0 +1,6 @@ +{{ define "main" }} + + {{ $pgs := where .Data.Pages "Params.hidden" "ne" "true" }} + {{ partial "postlist" $pgs }} + +{{ end }} -- cgit 1.4.1 From bb0d8756d02dd39375e6b67cd67fac850aec609a Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 11 Apr 2021 11:51:48 -0700 Subject: css: change font to roboto slab --- users/fcuny/blog/static/css/custom.css | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index 9d4faf1..b1a1957 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -1,13 +1,13 @@ -@import url('https://fonts.googleapis.com/css2?family=Roboto'); -@import url('https://fonts.googleapis.com/css?family=Roboto+Mono:400'); + @import url('https://fonts.googleapis.com/css2?family=Roboto+Slab&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap'); *, *:before, *:after { box-sizing: border-box; } body { background-color: #ffffff; line-height: 1.5rem; - font-size: 16px; - font-family: "Roboto", Arial, sans-serif; + font-size: 18px; + font-family: "Roboto Slab", serif; color: #000; padding: 2rem; } @@ -50,7 +50,7 @@ pre { padding: 1rem 2rem; margin: 0; font-size: 16px; - font-family: "Roboto Mono", Monaco, "Lucida Console", monospace; + font-family: 'Source Code Pro', monospace; overflow: scroll; } -- cgit 1.4.1 From 78b6e1e454ee36681078121d29ba4e66834c7011 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 11 Apr 2021 11:52:42 -0700 Subject: blog: google doc failure --- .../blog/content/notes/google-doc-failure.org | 56 ++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 users/fcuny/blog/content/notes/google-doc-failure.org (limited to 'users/fcuny') diff --git a/users/fcuny/blog/content/notes/google-doc-failure.org b/users/fcuny/blog/content/notes/google-doc-failure.org new file mode 100644 index 0000000..b4d449d --- /dev/null +++ b/users/fcuny/blog/content/notes/google-doc-failure.org @@ -0,0 +1,56 @@ +#+TITLE: Google Doc Failures +#+TAGS[]: documentation process +#+DATE: <2021-04-11 Sun> + +In most use cases, Google Doc is an effective tool to create "write once, read never" documents. + +* Convenience +Google Doc (GDoc from now on) is the most common way of writing and sharing documents at my current job. It's very easy to start a new document, even more since we can now point our browser to https://doc.new and start typing right away. + +Like most of my co-workers, I use it frequently during the day. Some of these documents are draft for some communication that I want others to review before I share with a broader audience; it can be a [[https://en.wikipedia.org/wiki/Request_for_Comments][Request For Comments]] for a project; meeting notes for others to read; information that I need to capture during an incident or a debugging session; interviews notes; etc. + +I would not be surprised if the teams I work closely with generate 50 new documents each week. +* ETOOMANYTABS +I have a tendency of having hundreds of open tabs in my browser during the week. A majority of these tabs are GDocs, and I think this is one of the true failure of the product. Why do I have so many tabs ? There's mainly two reasons. + +The first reason is a problem with Chrome's UX itself: it happily let me open the same URL as many times as I want in as many tabs, instead of sending me to the already opened tab if the document is loaded. It's not uncommon that I find the same document opened in 5 different tabs. + +The second reason, and it's the most important one, I know that if I need to read or comment on a doc and I close the tab, I'll likely never find that document again, or will completely forget about it. +* Discoverability +In 'the old days', you'd start a new document in Word or LibreOffice, and as you hit "save" for the first time, you've two decisions to make: how am I going to name that file, and where am I going to save it on disk. + +With GDoc these questions don't have to be answered, you don't have to name the file, and it does not matter where it lives. I've likely hundreds of docs named 'untitled' in my "drive". I also don't have to think about where they will live, because they are saved automatically for me. I'm sure there's hundreds of studies that show that these two simple steps are actually complex for many users and creates useless friction (in which folder do I store it; should I organize the docuemnts by team, years, projects; do I name it with the date and the current project; etc.). + +GDoc being a Google product, it seems pretty obvious that they would come up with a better solution: let's not organize in a strict hierarchy these files, and let's instead search for them. + +Unfortunately, GDoc's search is really poor (and I'm being kind). By default most of us start by looking for some words we know are in the doc, maybe even in the title. But when working on a multiple projects that are related to the same technology, you suddenly get hundreds of documents matching your query. It's unclear how the returned set is ordered (by date ? by author ? by some scoring that is invisible to me ?). + +You can also search by owners, but here is another annoying bit: I think about owner as author, so I usually type =author:foo= before realizing it does not work. And that implies you already know who's the owner of the document. In the case of TDDs (Technical Design Document), I might know which team is behind it, but rarely who's the actual author. + +I could search for the title, but I rarely remember or know the name of the document I'm looking for. I could also be looking by keywords, but when working on a project with tens of related documents, you have to open all the returned docs to see which one is the correct one. + +And then what about new members joining your the team ? They don't know which docs exist, who wrote them, and how they are named. They end up searching and hoping that something good will be returned. +* Workflows +More and more we create workflows around these documents: some of the docs are TDDs that are going through reviews; others are decision documents that require input from multiple teams and are pending approval; others are road map documents that also go through some review process. + +As a result we create templates for all kind of documents, with usually something like "draft → reviews → approved/rejected" at the top. We expect the owner of the doc to mark in bold what's the status of the doc to help the reader understand in what state the document is. It's difficult to keep track of open actions and comments. Yes, there's a way to get a list of all of them, but it's not in an obvious place. + +As a result, some engineers in my team built an external dashboard with swim lanes which captures the state of a document. We add new document with their URLs, add who are the reviewers, and we move the doc between the lanes. Now we have to operate a service and a database to keep track of the status of documents in GDoc. +* Alternatives +When it comes to technical document, I find that [[https://caitiem.com/2020/03/29/design-docs-markdown-and-git/][approach]] much more interesting. Some open source projects have adopted a similar workflow ([[https://github.com/kubernetes/enhancements/tree/master/keps][Kubernetes]], [[https://github.com/golang/proposal][Go]]). + +A new document starts its life as a text file (using what ever markup language your team/company prefers). The document is submitted for review, and the people who need to be consulted are added as reviewers. They can now comment on the document, the author can address them, mark them as resolved. It's clear in which state the document is: it's either in review, committed, or rejected. With this approach you also end up with a clear history, as time moves on you can amend the document by submitting a change, and the change goes through the same process. + +New comers will find the document in the repository, and if they want to see the conversation they can open the review associated with the original change. They can also see how the document evolved over time. It's also easy to publish these documents on an internal website, using a static site generator for example. + +One of the thing that I think are critical, is that all of that is done using the tools the engineers are already using for their day to day job: a text editor, a version control system, a code review tool. + +There's obviously challenges with this approach too: ++ *it's more heavy handed*: not every one likes to write in a text editor using a markup language. It can requires some time to learn or get used to the syntax ++ *it's harder to integrate schema / visuals*: but having them checked in in the repository also improves the discoverability + +It's also true that no all documents suffer the same challenges for discoverability: ++ meeting notes are usually linked to meeting invites (however if you were not part of the meeting, you end up with the same challenges to discover them) ++ drafts for communications are usually not relevant once the communication has been sent ++ interview notes are usually transferred to some tools for HR when the feedback is submitted + -- cgit 1.4.1 From 812975fb5e0cbe5ac32285eb7b6d5bac715d1988 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 11 Apr 2021 11:54:55 -0700 Subject: css: remove extra white space --- users/fcuny/blog/static/css/custom.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index b1a1957..505f66d 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -1,4 +1,4 @@ - @import url('https://fonts.googleapis.com/css2?family=Roboto+Slab&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Roboto+Slab&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap'); *, *:before, *:after { box-sizing: border-box; } -- cgit 1.4.1 From 503cfd7c57fae67d91a98789e5853ba28132b031 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 11 Apr 2021 15:44:29 -0700 Subject: css: switch to sans-serif; add tables; other tweaks --- users/fcuny/blog/static/css/custom.css | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index 505f66d..7592e8e 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -6,15 +6,15 @@ body { background-color: #ffffff; line-height: 1.5rem; - font-size: 18px; - font-family: "Roboto Slab", serif; + font-size: 16px; + font-family: "Roboto Slab", sans-serif; color: #000; padding: 2rem; } .main { margin: auto; - max-width: 50rem; + max-width: 60rem; } a { @@ -42,7 +42,7 @@ span.published, span.updated { font-style: oblique; } -code { +code.verbatim { background-color: #eeeeee; } @@ -51,7 +51,7 @@ pre { margin: 0; font-size: 16px; font-family: 'Source Code Pro', monospace; - overflow: scroll; + /* overflow: scroll; */ } .tags { @@ -69,3 +69,26 @@ pre { .meta_date { font-style: italic; } + +table { + border: 1px solid black; + width: 100%; + border-spacing: 15px; + border-collapse: collapse; + letter-spacing: 1px; + font-family: 'Source Code Pro', monospace; + font-size: 16px; + text-align: left; +} + +thead { + background-color: #E0EBF5; + font-weight: bold; +} + +blockquote { + background-color: #fffff0; + border-radius: 5px; + padding-left: 5px; + font-style: italic; +} -- cgit 1.4.1 From 492608f524e20e54d9eaa6d128e4fbb314732b69 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 11 Apr 2021 15:44:14 -0700 Subject: toml: re-configure markup --- users/fcuny/blog/config.toml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/config.toml b/users/fcuny/blog/config.toml index 23df087..31f75af 100644 --- a/users/fcuny/blog/config.toml +++ b/users/fcuny/blog/config.toml @@ -3,7 +3,6 @@ languageCode = "en-us" title = "Franck Cuny's Website" publishDir = "docs" enableGitInfo = true -markup = "org" [params] homeText = "A collection of notes" @@ -15,6 +14,24 @@ markup = "org" articles = "/:section/:slug/" tags = "/tags/:slug/" +[markup] + [markup.tableOfContents] + startLevel = 1 + endLevel = 3 + ordered = true + [markup.highlight] + anchorLineNos = false + codeFences = false + guessSyntax = false + hl_Lines = "" + lineAnchors = "" + lineNoStart = 1 + lineNos = false + lineNumbersInTable = false + noClasses = true + style = "emacs" + tabWidth = 4 + [mediaTypes."application/atom"] suffixes = ["xml"] -- cgit 1.4.1 From ef3fa6ba26fcf11fdd2325764147f56c90b94a7b Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Thu, 22 Apr 2021 12:44:27 -0700 Subject: layout: add a navbar I want to differentiate blog's entries from more general notes. For this, we create two menu entries, and add a navbar at the top. The nav bar let us select between the two kind of articles: blogs or notes. For now we have a single blog entry, and no notes. The page to list entries is simplified: we use the same layout for all lists (tags, notes, blogs). The CSS is updated to support the new nav bar. --- users/fcuny/blog/config.toml | 18 ++++++- .../fcuny/blog/content/blog/google-doc-failure.org | 56 ++++++++++++++++++++++ .../blog/content/notes/google-doc-failure.org | 56 ---------------------- users/fcuny/blog/layouts/_default/baseof.html | 1 + users/fcuny/blog/layouts/_default/list.html | 8 +--- users/fcuny/blog/layouts/_default/single.html | 2 - users/fcuny/blog/layouts/index.html | 8 ---- users/fcuny/blog/layouts/partials/header.html | 15 ++++++ users/fcuny/blog/layouts/partials/postlist.html | 20 +------- users/fcuny/blog/static/css/custom.css | 41 +++++++++++++++- 10 files changed, 131 insertions(+), 94 deletions(-) create mode 100644 users/fcuny/blog/content/blog/google-doc-failure.org delete mode 100644 users/fcuny/blog/content/notes/google-doc-failure.org create mode 100644 users/fcuny/blog/layouts/partials/header.html (limited to 'users/fcuny') diff --git a/users/fcuny/blog/config.toml b/users/fcuny/blog/config.toml index 31f75af..6100ba5 100644 --- a/users/fcuny/blog/config.toml +++ b/users/fcuny/blog/config.toml @@ -1,6 +1,6 @@ baseURL = "http://fcuny.net/" languageCode = "en-us" -title = "Franck Cuny's Website" +title = "Franck's rambling" publishDir = "docs" enableGitInfo = true @@ -11,9 +11,23 @@ enableGitInfo = true tag = "tags" [permalinks] - articles = "/:section/:slug/" + blog = "/blog/:slug/" + notes = "/notes/:slug/" tags = "/tags/:slug/" +[menu] + [[menu.main]] + identifier = "articles" + name = "blog" + title = "articles" + url = "/blog/" + + [[menu.main]] + identifier = "notes" + name = "notes" + title = "notes" + url = "/notes/" + [markup] [markup.tableOfContents] startLevel = 1 diff --git a/users/fcuny/blog/content/blog/google-doc-failure.org b/users/fcuny/blog/content/blog/google-doc-failure.org new file mode 100644 index 0000000..b4d449d --- /dev/null +++ b/users/fcuny/blog/content/blog/google-doc-failure.org @@ -0,0 +1,56 @@ +#+TITLE: Google Doc Failures +#+TAGS[]: documentation process +#+DATE: <2021-04-11 Sun> + +In most use cases, Google Doc is an effective tool to create "write once, read never" documents. + +* Convenience +Google Doc (GDoc from now on) is the most common way of writing and sharing documents at my current job. It's very easy to start a new document, even more since we can now point our browser to https://doc.new and start typing right away. + +Like most of my co-workers, I use it frequently during the day. Some of these documents are draft for some communication that I want others to review before I share with a broader audience; it can be a [[https://en.wikipedia.org/wiki/Request_for_Comments][Request For Comments]] for a project; meeting notes for others to read; information that I need to capture during an incident or a debugging session; interviews notes; etc. + +I would not be surprised if the teams I work closely with generate 50 new documents each week. +* ETOOMANYTABS +I have a tendency of having hundreds of open tabs in my browser during the week. A majority of these tabs are GDocs, and I think this is one of the true failure of the product. Why do I have so many tabs ? There's mainly two reasons. + +The first reason is a problem with Chrome's UX itself: it happily let me open the same URL as many times as I want in as many tabs, instead of sending me to the already opened tab if the document is loaded. It's not uncommon that I find the same document opened in 5 different tabs. + +The second reason, and it's the most important one, I know that if I need to read or comment on a doc and I close the tab, I'll likely never find that document again, or will completely forget about it. +* Discoverability +In 'the old days', you'd start a new document in Word or LibreOffice, and as you hit "save" for the first time, you've two decisions to make: how am I going to name that file, and where am I going to save it on disk. + +With GDoc these questions don't have to be answered, you don't have to name the file, and it does not matter where it lives. I've likely hundreds of docs named 'untitled' in my "drive". I also don't have to think about where they will live, because they are saved automatically for me. I'm sure there's hundreds of studies that show that these two simple steps are actually complex for many users and creates useless friction (in which folder do I store it; should I organize the docuemnts by team, years, projects; do I name it with the date and the current project; etc.). + +GDoc being a Google product, it seems pretty obvious that they would come up with a better solution: let's not organize in a strict hierarchy these files, and let's instead search for them. + +Unfortunately, GDoc's search is really poor (and I'm being kind). By default most of us start by looking for some words we know are in the doc, maybe even in the title. But when working on a multiple projects that are related to the same technology, you suddenly get hundreds of documents matching your query. It's unclear how the returned set is ordered (by date ? by author ? by some scoring that is invisible to me ?). + +You can also search by owners, but here is another annoying bit: I think about owner as author, so I usually type =author:foo= before realizing it does not work. And that implies you already know who's the owner of the document. In the case of TDDs (Technical Design Document), I might know which team is behind it, but rarely who's the actual author. + +I could search for the title, but I rarely remember or know the name of the document I'm looking for. I could also be looking by keywords, but when working on a project with tens of related documents, you have to open all the returned docs to see which one is the correct one. + +And then what about new members joining your the team ? They don't know which docs exist, who wrote them, and how they are named. They end up searching and hoping that something good will be returned. +* Workflows +More and more we create workflows around these documents: some of the docs are TDDs that are going through reviews; others are decision documents that require input from multiple teams and are pending approval; others are road map documents that also go through some review process. + +As a result we create templates for all kind of documents, with usually something like "draft → reviews → approved/rejected" at the top. We expect the owner of the doc to mark in bold what's the status of the doc to help the reader understand in what state the document is. It's difficult to keep track of open actions and comments. Yes, there's a way to get a list of all of them, but it's not in an obvious place. + +As a result, some engineers in my team built an external dashboard with swim lanes which captures the state of a document. We add new document with their URLs, add who are the reviewers, and we move the doc between the lanes. Now we have to operate a service and a database to keep track of the status of documents in GDoc. +* Alternatives +When it comes to technical document, I find that [[https://caitiem.com/2020/03/29/design-docs-markdown-and-git/][approach]] much more interesting. Some open source projects have adopted a similar workflow ([[https://github.com/kubernetes/enhancements/tree/master/keps][Kubernetes]], [[https://github.com/golang/proposal][Go]]). + +A new document starts its life as a text file (using what ever markup language your team/company prefers). The document is submitted for review, and the people who need to be consulted are added as reviewers. They can now comment on the document, the author can address them, mark them as resolved. It's clear in which state the document is: it's either in review, committed, or rejected. With this approach you also end up with a clear history, as time moves on you can amend the document by submitting a change, and the change goes through the same process. + +New comers will find the document in the repository, and if they want to see the conversation they can open the review associated with the original change. They can also see how the document evolved over time. It's also easy to publish these documents on an internal website, using a static site generator for example. + +One of the thing that I think are critical, is that all of that is done using the tools the engineers are already using for their day to day job: a text editor, a version control system, a code review tool. + +There's obviously challenges with this approach too: ++ *it's more heavy handed*: not every one likes to write in a text editor using a markup language. It can requires some time to learn or get used to the syntax ++ *it's harder to integrate schema / visuals*: but having them checked in in the repository also improves the discoverability + +It's also true that no all documents suffer the same challenges for discoverability: ++ meeting notes are usually linked to meeting invites (however if you were not part of the meeting, you end up with the same challenges to discover them) ++ drafts for communications are usually not relevant once the communication has been sent ++ interview notes are usually transferred to some tools for HR when the feedback is submitted + diff --git a/users/fcuny/blog/content/notes/google-doc-failure.org b/users/fcuny/blog/content/notes/google-doc-failure.org deleted file mode 100644 index b4d449d..0000000 --- a/users/fcuny/blog/content/notes/google-doc-failure.org +++ /dev/null @@ -1,56 +0,0 @@ -#+TITLE: Google Doc Failures -#+TAGS[]: documentation process -#+DATE: <2021-04-11 Sun> - -In most use cases, Google Doc is an effective tool to create "write once, read never" documents. - -* Convenience -Google Doc (GDoc from now on) is the most common way of writing and sharing documents at my current job. It's very easy to start a new document, even more since we can now point our browser to https://doc.new and start typing right away. - -Like most of my co-workers, I use it frequently during the day. Some of these documents are draft for some communication that I want others to review before I share with a broader audience; it can be a [[https://en.wikipedia.org/wiki/Request_for_Comments][Request For Comments]] for a project; meeting notes for others to read; information that I need to capture during an incident or a debugging session; interviews notes; etc. - -I would not be surprised if the teams I work closely with generate 50 new documents each week. -* ETOOMANYTABS -I have a tendency of having hundreds of open tabs in my browser during the week. A majority of these tabs are GDocs, and I think this is one of the true failure of the product. Why do I have so many tabs ? There's mainly two reasons. - -The first reason is a problem with Chrome's UX itself: it happily let me open the same URL as many times as I want in as many tabs, instead of sending me to the already opened tab if the document is loaded. It's not uncommon that I find the same document opened in 5 different tabs. - -The second reason, and it's the most important one, I know that if I need to read or comment on a doc and I close the tab, I'll likely never find that document again, or will completely forget about it. -* Discoverability -In 'the old days', you'd start a new document in Word or LibreOffice, and as you hit "save" for the first time, you've two decisions to make: how am I going to name that file, and where am I going to save it on disk. - -With GDoc these questions don't have to be answered, you don't have to name the file, and it does not matter where it lives. I've likely hundreds of docs named 'untitled' in my "drive". I also don't have to think about where they will live, because they are saved automatically for me. I'm sure there's hundreds of studies that show that these two simple steps are actually complex for many users and creates useless friction (in which folder do I store it; should I organize the docuemnts by team, years, projects; do I name it with the date and the current project; etc.). - -GDoc being a Google product, it seems pretty obvious that they would come up with a better solution: let's not organize in a strict hierarchy these files, and let's instead search for them. - -Unfortunately, GDoc's search is really poor (and I'm being kind). By default most of us start by looking for some words we know are in the doc, maybe even in the title. But when working on a multiple projects that are related to the same technology, you suddenly get hundreds of documents matching your query. It's unclear how the returned set is ordered (by date ? by author ? by some scoring that is invisible to me ?). - -You can also search by owners, but here is another annoying bit: I think about owner as author, so I usually type =author:foo= before realizing it does not work. And that implies you already know who's the owner of the document. In the case of TDDs (Technical Design Document), I might know which team is behind it, but rarely who's the actual author. - -I could search for the title, but I rarely remember or know the name of the document I'm looking for. I could also be looking by keywords, but when working on a project with tens of related documents, you have to open all the returned docs to see which one is the correct one. - -And then what about new members joining your the team ? They don't know which docs exist, who wrote them, and how they are named. They end up searching and hoping that something good will be returned. -* Workflows -More and more we create workflows around these documents: some of the docs are TDDs that are going through reviews; others are decision documents that require input from multiple teams and are pending approval; others are road map documents that also go through some review process. - -As a result we create templates for all kind of documents, with usually something like "draft → reviews → approved/rejected" at the top. We expect the owner of the doc to mark in bold what's the status of the doc to help the reader understand in what state the document is. It's difficult to keep track of open actions and comments. Yes, there's a way to get a list of all of them, but it's not in an obvious place. - -As a result, some engineers in my team built an external dashboard with swim lanes which captures the state of a document. We add new document with their URLs, add who are the reviewers, and we move the doc between the lanes. Now we have to operate a service and a database to keep track of the status of documents in GDoc. -* Alternatives -When it comes to technical document, I find that [[https://caitiem.com/2020/03/29/design-docs-markdown-and-git/][approach]] much more interesting. Some open source projects have adopted a similar workflow ([[https://github.com/kubernetes/enhancements/tree/master/keps][Kubernetes]], [[https://github.com/golang/proposal][Go]]). - -A new document starts its life as a text file (using what ever markup language your team/company prefers). The document is submitted for review, and the people who need to be consulted are added as reviewers. They can now comment on the document, the author can address them, mark them as resolved. It's clear in which state the document is: it's either in review, committed, or rejected. With this approach you also end up with a clear history, as time moves on you can amend the document by submitting a change, and the change goes through the same process. - -New comers will find the document in the repository, and if they want to see the conversation they can open the review associated with the original change. They can also see how the document evolved over time. It's also easy to publish these documents on an internal website, using a static site generator for example. - -One of the thing that I think are critical, is that all of that is done using the tools the engineers are already using for their day to day job: a text editor, a version control system, a code review tool. - -There's obviously challenges with this approach too: -+ *it's more heavy handed*: not every one likes to write in a text editor using a markup language. It can requires some time to learn or get used to the syntax -+ *it's harder to integrate schema / visuals*: but having them checked in in the repository also improves the discoverability - -It's also true that no all documents suffer the same challenges for discoverability: -+ meeting notes are usually linked to meeting invites (however if you were not part of the meeting, you end up with the same challenges to discover them) -+ drafts for communications are usually not relevant once the communication has been sent -+ interview notes are usually transferred to some tools for HR when the feedback is submitted - diff --git a/users/fcuny/blog/layouts/_default/baseof.html b/users/fcuny/blog/layouts/_default/baseof.html index d9ca51a..3fd7011 100644 --- a/users/fcuny/blog/layouts/_default/baseof.html +++ b/users/fcuny/blog/layouts/_default/baseof.html @@ -3,6 +3,7 @@ {{ partial "head.html" . }}
+ {{- partial "header.html" . -}}
{{ block "main" . }}{{ end }}
diff --git a/users/fcuny/blog/layouts/_default/list.html b/users/fcuny/blog/layouts/_default/list.html index 3423cb6..2b7d98a 100644 --- a/users/fcuny/blog/layouts/_default/list.html +++ b/users/fcuny/blog/layouts/_default/list.html @@ -1,10 +1,6 @@ {{ define "main" }} -

{{ .Title }}

-{{ range .Pages.ByPublishDate.Reverse }} -

- {{ .Title }} -

-{{ end }} + {{ $pgs := where .Data.Pages "Params.hidden" "ne" "true" }} + {{ partial "postlist" $pgs }} {{ end }} diff --git a/users/fcuny/blog/layouts/_default/single.html b/users/fcuny/blog/layouts/_default/single.html index 0ab5e35..356f344 100644 --- a/users/fcuny/blog/layouts/_default/single.html +++ b/users/fcuny/blog/layouts/_default/single.html @@ -1,7 +1,5 @@ {{ define "main" }} -

← Back to Franck's homepage

-

{{ .Title }}

diff --git a/users/fcuny/blog/layouts/index.html b/users/fcuny/blog/layouts/index.html index 450444b..f7581ff 100644 --- a/users/fcuny/blog/layouts/index.html +++ b/users/fcuny/blog/layouts/index.html @@ -11,12 +11,4 @@

I'm currently working as a Site Reliability Engineer at Twitter, on the Compute team.

-

Notes

- {{ $section := "notes" }} - - {{ end }} diff --git a/users/fcuny/blog/layouts/partials/header.html b/users/fcuny/blog/layouts/partials/header.html new file mode 100644 index 0000000..f918823 --- /dev/null +++ b/users/fcuny/blog/layouts/partials/header.html @@ -0,0 +1,15 @@ +
+ +
diff --git a/users/fcuny/blog/layouts/partials/postlist.html b/users/fcuny/blog/layouts/partials/postlist.html index 3695d82..28fd9b2 100644 --- a/users/fcuny/blog/layouts/partials/postlist.html +++ b/users/fcuny/blog/layouts/partials/postlist.html @@ -1,28 +1,10 @@ -

← Back to Franck's homepage

- -{{ range .GroupByDate "2006-Jan" }} +{{ range .GroupByDate "2006" }}

{{ .Key }}

    {{ range .Pages.ByDate }}
  • {{ .Title }}

    - {{ if .Params.tags }} -
    - Tags: - {{ range $idx, $tag := .Params.tags }} - {{ $tag }} - {{ end }} -
    - {{ else }} -
    - {{ end }} -
    -
    -

    - {{ .Summary }} - Read more → -

  • {{ end }} diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index 7592e8e..f363bee 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -38,7 +38,7 @@ h2 { } span.published, span.updated { - display: block; + display: center; font-style: oblique; } @@ -92,3 +92,42 @@ blockquote { padding-left: 5px; font-style: italic; } + +nav { + display: flex; + flex: 2 0px; + justify-content: flex-end; + padding-left: 1em; + margin: 0 auto; + line-height: 0.2rem; +} + +nav ul { + display: flex; + list-style-type: none; + margin: 0 +} + +nav a { + padding: 1em; + display: inline-block; + color: black; + font-family: sans-serif; + text-decoration: none; + transition: all 75ms ease-in; +} + +nav a:hover { + color: #fff; + background-color: #007d9c; +} + +nav a.menu-active:hover { + color: #fff; + background-color: #007d9c; +} + +nav a.menu-active { + color: #007d9c; +} + -- cgit 1.4.1 From 757e4e8a08637bb58a3231261ad2590ebd151705 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Thu, 22 Apr 2021 17:20:21 -0700 Subject: blog: containerd to firecracker --- .../content/notes/containerd-to-firecracker.org | 567 +++++++++++++++++++++ 1 file changed, 567 insertions(+) create mode 100644 users/fcuny/blog/content/notes/containerd-to-firecracker.org (limited to 'users/fcuny') diff --git a/users/fcuny/blog/content/notes/containerd-to-firecracker.org b/users/fcuny/blog/content/notes/containerd-to-firecracker.org new file mode 100644 index 0000000..bce21d8 --- /dev/null +++ b/users/fcuny/blog/content/notes/containerd-to-firecracker.org @@ -0,0 +1,567 @@ +#+TITLE: containerd to firecracker +#+DATE: <2021-05-15 Sat> +#+TAGS[]: linux, firecracker, containerd + +fly.io had an [[https://fly.io/blog/docker-without-docker/][interesting article]] about how they use docker images to create VMs for =firecracker=. + +They describe the process as follow: + +1. Pull a container from a registry +2. Create a loop device to store the container's filesystem on +3. Unpack the container into the mounted loop device +4. Create a second block device and inject init, kernel, configuration and other stuff +5. Attach persistent volumes (if any) +6. Create a TAP device and configure it +7. Hand it off to Firecracker and boot that thing + +That's pretty detailed, and I'm curious how difficult it is to implement this. I've been meaning to look into Firecracker for a while and into containers'd API, so this is a perfect opportunity to get started. + +* #1 Pull a container from a registry with =containerd= +=containerd= has a pretty [[https://pkg.go.dev/github.com/containerd/containerd][detailed documentation]]. From the main page we can see the following example to create a client. +#+begin_src go +import ( + "github.com/containerd/containerd" + "github.com/containerd/containerd/cio" +) + + +func main() { + client, err := containerd.New("/run/containerd/containerd.sock") + defer client.Close() +} +#+end_src + +And pulling an image is also pretty straightforward: +#+begin_src go +image, err := client.Pull(context, "docker.io/library/redis:latest") +#+end_src + +The =Pull= method returns an [[https://pkg.go.dev/github.com/containerd/containerd@v1.4.4/images#Image][=Image=]] and there's a few methods associated with it. + +As =containerd= has namespaces, it's possible to specify the namespace we want to use when working with the API: +#+begin_src go +ctx := namespaces.WithNamespace(context.Background(), "c2vm") +image, err := client.Pull(ctx, "docker.io/library/redis:latest") +#+end_src + +The image will now be stored in the =c2vm= namespace. We can verify this with: +#+begin_src sh +; sudo ctr -n c2vm images ls -q +docker.io/library/redis:latest +#+end_src + +* #2 Create a loop device to store the container's filesystem on +This is going to be pretty straightforward. To create a loop device we need to: +1. pre-allocate space to a file +2. convert that file to some format +3. mount it to some destination + +There's two commons ways to pre-allocate space to a file: =dd= and =fallocate= (there's likely way more ways to do this). I'll go with =fallocate= for this example. + +First, to be safe, we create a temporary file, and use =renameio= to handle the renaming (I recommend reading the doc of the module). + +#+begin_src go +f, err := renameio.TempFile("", rawFile) +if err != nil { + return err +} +defer f.Cleanup() +#+end_src + +Now to do the pre-allocation (we're making an assumption here that 2GB is enough, we can likely check what's the size of the container before doing this): +#+begin_src go +command := exec.Command("fallocate", "-l", "2G", f.Name()) +if err := command.Run(); err != nil { + return fmt.Errorf("fallocate error: %s", err) +} +#+end_src + +We can now convert that file to ext4: +#+begin_src go +command = exec.Command("mkfs.ext4", "-F", f.Name()) +if err := command.Run(); err != nil { + return fmt.Errorf("mkfs.ext4 error: %s", err) +} +#+end_src + +Now we can rename safely the temporary file to the proper file we want: +#+begin_src go +f.CloseAtomicallyReplace() +#+end_src + +And to mount that file +#+begin_src go +command = exec.Command("mount", "-o", "loop", rawFile, mntDir) +if err := command.Run(); err != nil { + return fmt.Errorf("mount error: %s", err) +} +#+end_src +* #3 Unpack the container into the mounted loop device +Extracting the container using =containerd= is pretty simple. Here's the function that I use: +#+begin_src go +func extract(ctx context.Context, client *containerd.Client, image containerd.Image, mntDir string) error { + manifest, err := images.Manifest(ctx, client.ContentStore(), image.Target(), platform) + if err != nil { + log.Fatalf("failed to get the manifest: %v\n", err) + } + + for _, desc := range manifest.Layers { + log.Printf("extracting layer %s\n", desc.Digest.String()) + layer, err := client.ContentStore().ReaderAt(ctx, desc) + if err != nil { + return err + } + if err := archive.Untar(content.NewReader(layer), mntDir, &archive.TarOptions{NoLchown: true}); err != nil { + return err + } + } + + return nil +} +#+end_src + +Calling =images.Manifest= returns the [[https://github.com/opencontainers/image-spec/blob/master/manifest.md][manifest]] from the image. What we care here are the list of layers. Here I'm making a number of assumptions regarding their type (we should be checking the media type first). We read the layers and extract them to the mounted path. +* #4 Create a second block device and inject other stuff +Here I'm going to deviate a bit. I will not create a second loop device, and I will not inject a kernel. In their article, they provided a link to a snapshot of their =init= process (https://github.com/superfly/init-snapshot). In order to keep this simple, our init is going to be a shell script composed of the content of the entry point of the container. We're also going to add a few extra files to container (=/etc/hosts= and =/etc/resolv.conf=). + +Finally, since we've pre-allocated 2GB for that container, and we likely don't need that much, we're also going to resize the image. +** Add init +Let's refer to the [[https://github.com/opencontainers/image-spec/blob/master/config.md][specification for the config]]. The elements that are of interest to me are: +- =Env=, which is array of strings. They contain the environment variables that likely we need to run the program +- =Cmd=, which is also an array of strings. If there's no entry point provided, this is what is used. + +At this point, for this experiment, I'm going to ignore exposed ports, working directory, and the user. + +First we need to read the config from the container. This is easily done: +#+begin_src go +config, err := images.Config(ctx, client.ContentStore(), image.Target(), platform) +if err != nil { + return err +} +#+end_src + +This needs to be read and decoded: +#+begin_src go +configBlob, err := content.ReadBlob(ctx, client.ContentStore(), config) +var imageSpec ocispec.Image +json.Unmarshal(configBlob, &imageSpec) +#+end_src + +=init= is the first process started by Linux during boot. On a regular Linux desktop you likely have a symbolic link from =/usr/bin/init= to =/usr/lib/systemd/systemd=, since most distributions have switched to =systemd=. For my use case however, I want to run a single process, and I want it to be the one from the container. For this we can create a simple shell script inside the container (the location does not matter for now) with the environment variables and the command. + +Naively, this can be done like this: +#+begin_src go +initPath := filepath.Join(mntDir, "init.sh") +f, err := renameio.TempFile("", initPath) +if err != nil { + return err +} +defer f.Cleanup() + +writer := bufio.NewWriter(f) +fmt.Fprintf(writer, "#!/bin/sh\n") +for _, env := range initEnvs { + fmt.Fprintf(writer, "export %s\n", env) +} +fmt.Fprintf(writer, "%s\n", initCmd) +writer.Flush() + +f.CloseAtomicallyReplace() + +mode := int(0755) +os.Chmod(initPath, os.FileMode(mode)) +#+end_src + +We're once again creating a temporary file with =renamio=, and we're writing our shell scripts, one line at a time. We only need to make sure this executable. +** extra files +Once we have our init file, I also want to add a few extra files: =/etc/hosts= and =/etc/resolv.conf=. This files are not always present, since they can be injected by other systems. I also want to make sure that DNS resolutions are done using my own DNS server. +** resize the image +We've pre-allocated 2GB for the image, and it's likely we don't need as much space. We can do this by running =e2fsck= and =resize2fs= once we're done manipulating the image. + +Within a function, we can do the following: +#+begin_src go +command := exec.Command("/usr/bin/e2fsck", "-p", "-f", rawFile) +if err := command.Run(); err != nil { + return fmt.Errorf("e2fsck error: %s", err) +} + +command = exec.Command("resize2fs", "-M", rawFile) +if err := command.Run(); err != nil { + return fmt.Errorf("resize2fs error: %s", err) +} +#+end_src + +I'm using =docker.io/library/redis:latest= for my test, and I end up with the following size for the image: +#+begin_src bash +-rw------- 1 root root 216M Apr 22 14:50 /tmp/fcuny.img +#+end_src +** Kernel +We're going to need a kernel to run that VM. In my case I've decided to go with version 5.8, and build a custom kernel. If you are not familiar with the process, the firecracker team has [[https://github.com/firecracker-microvm/firecracker/blob/main/docs/rootfs-and-kernel-setup.md#creating-a-kernel-image][documented how to do this]]. In my case all I had to do was: +#+begin_src sh +git clone https://github.com/torvalds/linux.git linux.git +cd linux.git +git checkout v5.8 +curl -o .config -s https://github.com/firecracker-microvm/firecracker/blob/main/resources/microvm-kernel-x86_64.config +make menuconfig +make vmlinux -j8 +#+end_src + +Note that they also have a pretty [[https://github.com/firecracker-microvm/firecracker/blob/main/docs/prod-host-setup.md][good documentation for production]]. +* #5 Attach persistent volumes (if any) +I'm going to skip that step for now. +* #6 Create a TAP device and configure it +We're going to need a network for that VM (otherwise it might be a bit boring). +There's a few solutions that we can take: +1. create the TAP device +2. delegate all that work to a [[https://github.com/containernetworking/cni][CNI]] + +I've decided to use the CNI approach [[https://github.com/firecracker-microvm/firecracker-go-sdk#cni][documented in the Go's SDK]]. For this to work we need to install the =tc-redirect-tap= CNI plugin (available at https://github.com/awslabs/tc-redirect-tap). + +Based on that documentation, I'll start with the following configuration in =etc/cni/conf.d/50-c2vm.conflist=: +#+begin_src json +{ + "name": "c2vm", + "cniVersion": "0.4.0", + "plugins": [ + { + "type": "bridge", + "bridge": "c2vm-br", + "isDefaultGateway": true, + "forceAddress": false, + "ipMasq": true, + "hairpinMode": true, + "mtu": 1500, + "ipam": { + "type": "host-local", + "subnet": "192.168.128.0/24", + "resolvConf": "/etc/resolv.conf" + } + }, + { + "type": "firewall" + }, + { + "type": "tc-redirect-tap" + } + ] +} +#+end_src +* #7 Hand it off to Firecracker and boot that thing +Now that we have all the components, we need to boot that VM. Since I've been working with Go so far, I'll also use the [[https://github.com/firecracker-microvm/firecracker-go-sdk][Go SDK]] to manage and start the VM. + +For this we need the firecracker binary, which we can [[https://github.com/firecracker-microvm/firecracker/releases][find on GitHub]]. + +The first thing is to configure the list of devices. In our case we will have a single device, the boot drive that we've created in the previous step. +#+begin_src go +devices := make([]models.Drive, 1) +devices[0] = models.Drive{ + DriveID: firecracker.String("1"), + PathOnHost: &rawImage, + IsRootDevice: firecracker.Bool(true), + IsReadOnly: firecracker.Bool(false), +} +#+end_src + +The next step is to configure the VM: +#+begin_src go +fcCfg := firecracker.Config{ + LogLevel: "debug", + SocketPath: firecrackerSock, + KernelImagePath: linuxKernel, + KernelArgs: "console=ttyS0 reboot=k panic=1 pci=off init=/init.sh random.trust_cpu=on", + Drives: devices, + MachineCfg: models.MachineConfiguration{ + VcpuCount: firecracker.Int64(1), + CPUTemplate: models.CPUTemplate("C3"), + HtEnabled: firecracker.Bool(true), + MemSizeMib: firecracker.Int64(512), + }, + NetworkInterfaces: []firecracker.NetworkInterface{ + { + CNIConfiguration: &firecracker.CNIConfiguration{ + NetworkName: "c2vm", + IfName: "eth0", + }, + }, + }, +} +#+end_src + +Finally we can create the command to start and run the VM: +#+begin_src go +command := firecracker.VMCommandBuilder{}. + WithBin(firecrackerBinary). + WithSocketPath(fcCfg.SocketPath). + WithStdin(os.Stdin). + WithStdout(os.Stdout). + WithStderr(os.Stderr). + Build(ctx) +machineOpts = append(machineOpts, firecracker.WithProcessRunner(command)) +m, err := firecracker.NewMachine(vmmCtx, fcCfg, machineOpts...) +if err != nil { + panic(err) +} + +if err := m.Start(vmmCtx); err != nil { + panic(err) +} +defer m.StopVMM() + +if err := m.Wait(vmmCtx); err != nil { + panic(err) +} +#+end_src + +The end result: +#+begin_src +; sudo ./c2vm -container docker.io/library/redis:latest -firecracker-binary ./hack/firecracker/firecracker-v0.24.3-x86_64 -linux-kernel ./hack/linux/my-linux.bin -out /tmp/redis.img +2021/05/15 14:12:59 pulled docker.io/library/redis:latest (38690247 bytes) +2021/05/15 14:13:00 mounted /tmp/redis.img on /tmp/c2vm026771514 +2021/05/15 14:13:00 extracting layer sha256:69692152171afee1fd341febc390747cfca2ff302f2881d8b394e786af605696 +2021/05/15 14:13:00 extracting layer sha256:a4a46f2fd7e06fab84b4e78eb2d1b6d007351017f9b18dbeeef1a9e7cf194e00 +2021/05/15 14:13:00 extracting layer sha256:bcdf6fddc3bdaab696860eb0f4846895c53a3192c9d7bf8d2275770ea8073532 +2021/05/15 14:13:01 extracting layer sha256:b7e9b50900cc06838c44e0fc5cbebe5c0b3e7f70c02f32dd754e1aa6326ed566 +2021/05/15 14:13:01 extracting layer sha256:5f3030c50d85a9d2f70adb610b19b63290c6227c825639b227ddc586f86d1c76 +2021/05/15 14:13:01 extracting layer sha256:63dae8e0776cdbd63909fbd9c047c1615a01cb21b73efa87ae2feed680d3ffa1 +2021/05/15 14:13:01 init script created +2021/05/15 14:13:01 umount /tmp/c2vm026771514 +INFO[0003] Called startVMM(), setting up a VMM on firecracker.sock +INFO[0003] VMM logging disabled. +INFO[0003] VMM metrics disabled. +INFO[0003] refreshMachineConfiguration: [GET /machine-config][200] getMachineConfigurationOK &{CPUTemplate:C3 HtEnabled:0xc0004e6753 MemSizeMib:0xc0004e6748 VcpuCount:0xc0004e6740} +INFO[0003] PutGuestBootSource: [PUT /boot-source][204] putGuestBootSourceNoContent +INFO[0003] Attaching drive /tmp/redis.img, slot 1, root true. +INFO[0003] Attached drive /tmp/redis.img: [PUT /drives/{drive_id}][204] putGuestDriveByIdNoContent +INFO[0003] Attaching NIC tap0 (hwaddr 9e:72:c7:04:6b:80) at index 1 +INFO[0003] startInstance successful: [PUT /actions][204] createSyncActionNoContent +[ 0.000000] Linux version 5.8.0 (fcuny@nas) (gcc (Debian 8.3.0-6) 8.3.0, GNU ld (GNU Binutils for Debian) 2.31.1) #1 SMP Mon Apr 12 20:07:40 PDT 2021 +[ 0.000000] Command line: i8042.dumbkbd ip=192.168.128.9::192.168.128.1:255.255.255.0:::off::: console=ttyS0 reboot=k panic=1 acpi=off pci=off i8042.noaux i8042.nomux i8042.nopnp init=/init.sh random.trust_cpu=on root=/dev/vda rw virtio_mmio.device=4K@0xd0000000:5 virtio_mmio.device=4K@0xd0001000:6 +[ 0.000000] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers' +[ 0.000000] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers' +[ 0.000000] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers' +[ 0.000000] x86/fpu: xstate_offset[2]: 576, xstate_sizes[2]: 256 +[ 0.000000] x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, using 'standard' format. +[ 0.000000] BIOS-provided physical RAM map: +[ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable +[ 0.000000] BIOS-e820: [mem 0x0000000000100000-0x000000001fffffff] usable +[ 0.000000] NX (Execute Disable) protection: active +[ 0.000000] DMI not present or invalid. +[ 0.000000] Hypervisor detected: KVM +[ 0.000000] kvm-clock: Using msrs 4b564d01 and 4b564d00 +[ 0.000000] kvm-clock: cpu 0, msr 2401001, primary cpu clock +[ 0.000000] kvm-clock: using sched offset of 11918596 cycles +[ 0.000005] clocksource: kvm-clock: mask: 0xffffffffffffffff max_cycles: 0x1cd42e4dffb, max_idle_ns: 881590591483 ns +[ 0.000011] tsc: Detected 1190.400 MHz processor +[ 0.000108] last_pfn = 0x20000 max_arch_pfn = 0x400000000 +[ 0.000151] Disabled +[ 0.000156] x86/PAT: MTRRs disabled, skipping PAT initialization too. +[ 0.000166] CPU MTRRs all blank - virtualized system. +[ 0.000170] x86/PAT: Configuration [0-7]: WB WT UC- UC WB WT UC- UC +[ 0.000201] found SMP MP-table at [mem 0x0009fc00-0x0009fc0f] +[ 0.000257] check: Scanning 1 areas for low memory corruption +[ 0.000364] No NUMA configuration found +[ 0.000365] Faking a node at [mem 0x0000000000000000-0x000000001fffffff] +[ 0.000370] NODE_DATA(0) allocated [mem 0x1ffde000-0x1fffffff] +[ 0.000490] Zone ranges: +[ 0.000493] DMA [mem 0x0000000000001000-0x0000000000ffffff] +[ 0.000494] DMA32 [mem 0x0000000001000000-0x000000001fffffff] +[ 0.000495] Normal empty +[ 0.000497] Movable zone start for each node +[ 0.000500] Early memory node ranges +[ 0.000501] node 0: [mem 0x0000000000001000-0x000000000009efff] +[ 0.000502] node 0: [mem 0x0000000000100000-0x000000001fffffff] +[ 0.000510] Zeroed struct page in unavailable ranges: 98 pages +[ 0.000511] Initmem setup node 0 [mem 0x0000000000001000-0x000000001fffffff] +[ 0.004990] Intel MultiProcessor Specification v1.4 +[ 0.004995] MPTABLE: OEM ID: FC +[ 0.004995] MPTABLE: Product ID: 000000000000 +[ 0.004996] MPTABLE: APIC at: 0xFEE00000 +[ 0.005007] Processor #0 (Bootup-CPU) +[ 0.005039] IOAPIC[0]: apic_id 2, version 17, address 0xfec00000, GSI 0-23 +[ 0.005041] Processors: 1 +[ 0.005042] TSC deadline timer available +[ 0.005044] smpboot: Allowing 1 CPUs, 0 hotplug CPUs +[ 0.005060] KVM setup pv remote TLB flush +[ 0.005072] KVM setup pv sched yield +[ 0.005078] PM: hibernation: Registered nosave memory: [mem 0x00000000-0x00000fff] +[ 0.005079] PM: hibernation: Registered nosave memory: [mem 0x0009f000-0x000fffff] +[ 0.005081] [mem 0x20000000-0xffffffff] available for PCI devices +[ 0.005082] Booting paravirtualized kernel on KVM +[ 0.005084] clocksource: refined-jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645519600211568 ns +[ 0.005087] setup_percpu: NR_CPUS:128 nr_cpumask_bits:128 nr_cpu_ids:1 nr_node_ids:1 +[ 0.006381] percpu: Embedded 44 pages/cpu s143360 r8192 d28672 u2097152 +[ 0.006404] KVM setup async PF for cpu 0 +[ 0.006410] kvm-stealtime: cpu 0, msr 1f422080 +[ 0.006420] Built 1 zonelists, mobility grouping on. Total pages: 128905 +[ 0.006420] Policy zone: DMA32 +[ 0.006422] Kernel command line: i8042.dumbkbd ip=192.168.128.9::192.168.128.1:255.255.255.0:::off::: console=ttyS0 reboot=k panic=1 acpi=off pci=off i8042.noaux i8042.nomux i8042.nopnp init=/init.sh random.trust_cpu=on root=/dev/vda rw virtio_mmio.device=4K@0xd0000000:5 virtio_mmio.device=4K@0xd0001000:6 +[ 0.006858] Dentry cache hash table entries: 65536 (order: 7, 524288 bytes, linear) +[ 0.007003] Inode-cache hash table entries: 32768 (order: 6, 262144 bytes, linear) +[ 0.007047] mem auto-init: stack:off, heap alloc:off, heap free:off +[ 0.007947] Memory: 491940K/523896K available (10243K kernel code, 629K rwdata, 1860K rodata, 1408K init, 6048K bss, 31956K reserved, 0K cma-reserved) +[ 0.007980] random: get_random_u64 called from __kmem_cache_create+0x3d/0x540 with crng_init=0 +[ 0.008053] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1 +[ 0.008146] rcu: Hierarchical RCU implementation. +[ 0.008147] rcu: RCU restricting CPUs from NR_CPUS=128 to nr_cpu_ids=1. +[ 0.008151] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies. +[ 0.008152] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1 +[ 0.008170] NR_IRQS: 4352, nr_irqs: 48, preallocated irqs: 16 +[ 0.008373] random: crng done (trusting CPU's manufacturer) +[ 0.008430] Console: colour dummy device 80x25 +[ 0.052276] printk: console [ttyS0] enabled +[ 0.052685] APIC: Switch to symmetric I/O mode setup +[ 0.053288] x2apic enabled +[ 0.053705] Switched APIC routing to physical x2apic. +[ 0.054213] KVM setup pv IPIs +[ 0.055559] clocksource: tsc-early: mask: 0xffffffffffffffff max_cycles: 0x1128af0325d, max_idle_ns: 440795261011 ns +[ 0.056516] Calibrating delay loop (skipped) preset value.. 2380.80 BogoMIPS (lpj=4761600) +[ 0.057259] pid_max: default: 32768 minimum: 301 +[ 0.057726] LSM: Security Framework initializing +[ 0.058176] SELinux: Initializing. +[ 0.058556] Mount-cache hash table entries: 1024 (order: 1, 8192 bytes, linear) +[ 0.059221] Mountpoint-cache hash table entries: 1024 (order: 1, 8192 bytes, linear) +[ 0.060382] x86/cpu: User Mode Instruction Prevention (UMIP) activated +[ 0.060510] Last level iTLB entries: 4KB 0, 2MB 0, 4MB 0 +[ 0.060510] Last level dTLB entries: 4KB 0, 2MB 0, 4MB 0, 1GB 0 +[ 0.060510] Spectre V1 : Mitigation: usercopy/swapgs barriers and __user pointer sanitization +[ 0.060510] Spectre V2 : Mitigation: Enhanced IBRS +[ 0.060510] Spectre V2 : Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch +[ 0.060510] Spectre V2 : mitigation: Enabling conditional Indirect Branch Prediction Barrier +[ 0.060510] Speculative Store Bypass: Mitigation: Speculative Store Bypass disabled via prctl and seccomp +[ 0.060510] Freeing SMP alternatives memory: 32K +[ 0.060510] smpboot: CPU0: Intel(R) Xeon(R) Processor @ 1.20GHz (family: 0x6, model: 0x3e, stepping: 0x4) +[ 0.060510] Performance Events: unsupported p6 CPU model 62 no PMU driver, software events only. +[ 0.060510] rcu: Hierarchical SRCU implementation. +[ 0.060510] smp: Bringing up secondary CPUs ... +[ 0.060510] smp: Brought up 1 node, 1 CPU +[ 0.060510] smpboot: Max logical packages: 1 +[ 0.060523] smpboot: Total of 1 processors activated (2380.80 BogoMIPS) +[ 0.061338] devtmpfs: initialized +[ 0.061710] x86/mm: Memory block size: 128MB +[ 0.062341] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns +[ 0.063245] futex hash table entries: 256 (order: 2, 16384 bytes, linear) +[ 0.063946] thermal_sys: Registered thermal governor 'fair_share' +[ 0.063946] thermal_sys: Registered thermal governor 'step_wise' +[ 0.064522] thermal_sys: Registered thermal governor 'user_space' +[ 0.065313] NET: Registered protocol family 16 +[ 0.066398] DMA: preallocated 128 KiB GFP_KERNEL pool for atomic allocations +[ 0.067057] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA pool for atomic allocations +[ 0.067778] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations +[ 0.068506] audit: initializing netlink subsys (disabled) +[ 0.068708] cpuidle: using governor ladder +[ 0.069097] cpuidle: using governor menu +[ 0.070636] audit: type=2000 audit(1621113181.800:1): state=initialized audit_enabled=0 res=1 +[ 0.076346] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages +[ 0.077007] ACPI: Interpreter disabled. +[ 0.077445] SCSI subsystem initialized +[ 0.077812] pps_core: LinuxPPS API ver. 1 registered +[ 0.078277] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti +[ 0.079206] PTP clock support registered +[ 0.079741] NetLabel: Initializing +[ 0.080111] NetLabel: domain hash size = 128 +[ 0.080529] NetLabel: protocols = UNLABELED CIPSOv4 CALIPSO +[ 0.081113] NetLabel: unlabeled traffic allowed by default +[ 0.082072] clocksource: Switched to clocksource kvm-clock +[ 0.082715] VFS: Disk quotas dquot_6.6.0 +[ 0.083123] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes) +[ 0.083855] pnp: PnP ACPI: disabled +[ 0.084510] NET: Registered protocol family 2 +[ 0.084718] tcp_listen_portaddr_hash hash table entries: 256 (order: 0, 4096 bytes, linear) +[ 0.085602] TCP established hash table entries: 4096 (order: 3, 32768 bytes, linear) +[ 0.086365] TCP bind hash table entries: 4096 (order: 4, 65536 bytes, linear) +[ 0.087025] TCP: Hash tables configured (established 4096 bind 4096) +[ 0.087749] UDP hash table entries: 256 (order: 1, 8192 bytes, linear) +[ 0.088481] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear) +[ 0.089261] NET: Registered protocol family 1 +[ 0.090395] virtio-mmio: Registering device virtio-mmio.0 at 0xd0000000-0xd0000fff, IRQ 5. +[ 0.091388] virtio-mmio: Registering device virtio-mmio.1 at 0xd0001000-0xd0001fff, IRQ 6. +[ 0.092222] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x1128af0325d, max_idle_ns: 440795261011 ns +[ 0.093322] clocksource: Switched to clocksource tsc +[ 0.093824] platform rtc_cmos: registered platform RTC device (no PNP device found) +[ 0.094618] check: Scanning for low memory corruption every 60 seconds +[ 0.095394] Initialise system trusted keyrings +[ 0.095836] Key type blacklist registered +[ 0.096427] workingset: timestamp_bits=36 max_order=17 bucket_order=0 +[ 0.097849] squashfs: version 4.0 (2009/01/31) Phillip Lougher +[ 0.107488] Key type asymmetric registered +[ 0.107905] Asymmetric key parser 'x509' registered +[ 0.108409] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252) +[ 0.109435] Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled +[ 0.110116] serial8250: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A +[ 0.111877] loop: module loaded +[ 0.112426] virtio_blk virtio0: [vda] 441152 512-byte logical blocks (226 MB/215 MiB) +[ 0.113229] vda: detected capacity change from 0 to 225869824 +[ 0.114143] Loading iSCSI transport class v2.0-870. +[ 0.114753] iscsi: registered transport (tcp) +[ 0.115162] tun: Universal TUN/TAP device driver, 1.6 +[ 0.115955] i8042: PNP detection disabled +[ 0.116498] serio: i8042 KBD port at 0x60,0x64 irq 1 +[ 0.117089] input: AT Raw Set 2 keyboard as /devices/platform/i8042/serio0/input/input0 +[ 0.117932] intel_pstate: CPU model not supported +[ 0.118448] hid: raw HID events driver (C) Jiri Kosina +[ 0.119090] Initializing XFRM netlink socket +[ 0.119555] NET: Registered protocol family 10 +[ 0.120285] Segment Routing with IPv6 +[ 0.120812] NET: Registered protocol family 17 +[ 0.121350] Bridge firewalling registered +[ 0.122026] NET: Registered protocol family 40 +[ 0.122515] IPI shorthand broadcast: enabled +[ 0.122961] sched_clock: Marking stable (72512224, 48198862)->(137683636, -16972550) +[ 0.123796] registered taskstats version 1 +[ 0.124203] Loading compiled-in X.509 certificates +[ 0.125355] Loaded X.509 cert 'Build time autogenerated kernel key: 6203e6adc37b712d3b220a26b38f3d31311d5966' +[ 0.126355] Key type ._fscrypt registered +[ 0.126736] Key type .fscrypt registered +[ 0.127109] Key type fscrypt-provisioning registered +[ 0.127657] Key type encrypted registered +[ 0.144629] IP-Config: Complete: +[ 0.144968] device=eth0, hwaddr=9e:72:c7:04:6b:80, ipaddr=192.168.128.9, mask=255.255.255.0, gw=192.168.128.1 +[ 0.146044] host=192.168.128.9, domain=, nis-domain=(none) +[ 0.146604] bootserver=255.255.255.255, rootserver=255.255.255.255, rootpath= +[ 0.148347] EXT4-fs (vda): mounted filesystem with ordered data mode. Opts: (null) +[ 0.149098] VFS: Mounted root (ext4 filesystem) on device 254:0. +[ 0.149761] devtmpfs: mounted +[ 0.150340] Freeing unused decrypted memory: 2040K +[ 0.151148] Freeing unused kernel image (initmem) memory: 1408K +[ 0.156621] Write protecting the kernel read-only data: 14336k +[ 0.158657] Freeing unused kernel image (text/rodata gap) memory: 2044K +[ 0.159490] Freeing unused kernel image (rodata/data gap) memory: 188K +[ 0.160150] Run /init.sh as init process +462:C 15 May 2021 21:13:01.903 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo +462:C 15 May 2021 21:13:01.904 # Redis version=6.2.3, bits=64, commit=00000000, modified=0, pid=462, just started +462:C 15 May 2021 21:13:01.905 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf +462:M 15 May 2021 21:13:01.907 * Increased maximum number of open files to 10032 (it was originally set to 1024). +462:M 15 May 2021 21:13:01.909 * monotonic clock: POSIX clock_gettime + _._ + _.-``__ ''-._ + _.-`` `. `_. ''-._ Redis 6.2.3 (00000000/0) 64 bit + .-`` .-```. ```\/ _.,_ ''-._ + ( ' , .-` | `, ) Running in standalone mode + |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 + | `-._ `._ / _.-' | PID: 462 + `-._ `-._ `-./ _.-' _.-' + |`-._`-._ `-.__.-' _.-'_.-'| + | `-._`-._ _.-'_.-' | https://redis.io + `-._ `-._`-.__.-'_.-' _.-' + |`-._`-._ `-.__.-' _.-'_.-'| + | `-._`-._ _.-'_.-' | + `-._ `-._`-.__.-'_.-' _.-' + `-._ `-.__.-' _.-' + `-._ _.-' + `-.__.-' + +462:M 15 May 2021 21:13:01.922 # Server initialized +462:M 15 May 2021 21:13:01.923 * Ready to accept connections +#+end_src + +We can do a quick test with the following: +#+begin_src sh +; sudo docker run -it --rm redis redis-cli -h 192.168.128.9 +192.168.128.9:6379> get foo +(nil) +192.168.128.9:6379> set foo 1 +OK +192.168.128.9:6379> get foo +"1" +192.168.128.9:6379> +#+end_src -- cgit 1.4.1 From a90e6adf70d955ec51158cc25782b40cd61314d8 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 18 May 2021 19:44:16 -0700 Subject: css: add a scroll bar if the content overflows --- users/fcuny/blog/static/css/custom.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index f363bee..18c9c41 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -51,7 +51,7 @@ pre { margin: 0; font-size: 16px; font-family: 'Source Code Pro', monospace; - /* overflow: scroll; */ + overflow-x: auto; } .tags { -- cgit 1.4.1 From aa2171e0283953ed06bb78254f715e42129c9989 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Wed, 19 May 2021 19:09:38 -0700 Subject: blog: update to containerd article Fix boot options --- users/fcuny/blog/content/notes/containerd-to-firecracker.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/content/notes/containerd-to-firecracker.org b/users/fcuny/blog/content/notes/containerd-to-firecracker.org index bce21d8..fd41b1d 100644 --- a/users/fcuny/blog/content/notes/containerd-to-firecracker.org +++ b/users/fcuny/blog/content/notes/containerd-to-firecracker.org @@ -268,7 +268,7 @@ fcCfg := firecracker.Config{ LogLevel: "debug", SocketPath: firecrackerSock, KernelImagePath: linuxKernel, - KernelArgs: "console=ttyS0 reboot=k panic=1 pci=off init=/init.sh random.trust_cpu=on", + KernelArgs: "console=ttyS0 reboot=k panic=1 acpi=off pci=off i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd init=/init.sh random.trust_cpu=on", Drives: devices, MachineCfg: models.MachineConfiguration{ VcpuCount: firecracker.Int64(1), -- cgit 1.4.1 From 4f60f7c193a33b22d73c3dfd2e382f496ad4f9c4 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 20 Jun 2021 13:12:56 -0700 Subject: fly: add configuration for fly.io --- users/fcuny/blog/fly.toml | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 users/fcuny/blog/fly.toml (limited to 'users/fcuny') diff --git a/users/fcuny/blog/fly.toml b/users/fcuny/blog/fly.toml new file mode 100644 index 0000000..46468c1 --- /dev/null +++ b/users/fcuny/blog/fly.toml @@ -0,0 +1,40 @@ +# fly.toml file generated for fcunynet on 2021-06-20T10:01:50-07:00 + +app = "fcunynet" + +kill_signal = "SIGINT" +kill_timeout = 5 + +[build] + builtin = "hugo-static" + +[env] + +[experimental] + allowed_public_ports = [] + auto_rollback = true + +[[services]] + http_checks = [] + internal_port = 8080 + protocol = "tcp" + script_checks = [] + + [services.concurrency] + hard_limit = 25 + soft_limit = 20 + type = "connections" + + [[services.ports]] + handlers = ["http"] + port = 80 + + [[services.ports]] + handlers = ["tls", "http"] + port = 443 + + [[services.tcp_checks]] + grace_period = "1s" + interval = "15s" + restart_limit = 6 + timeout = "2s" -- cgit 1.4.1 From d051d5a474461628ae3af941fd65b8976df52a26 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 20 Jun 2021 13:13:18 -0700 Subject: hugo: don't enable git info The docker image used by fly.io to deploy a static website with hugo does not come with git, which prevents us to use the option `enableGitInfo`. This is not critical for now, so let's disable it so we can deploy. --- users/fcuny/blog/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/config.toml b/users/fcuny/blog/config.toml index 6100ba5..532ff03 100644 --- a/users/fcuny/blog/config.toml +++ b/users/fcuny/blog/config.toml @@ -2,7 +2,7 @@ baseURL = "http://fcuny.net/" languageCode = "en-us" title = "Franck's rambling" publishDir = "docs" -enableGitInfo = true +enableGitInfo = false [params] homeText = "A collection of notes" -- cgit 1.4.1 From dbbe3acc765616a9d66496afaee6854b250ca22b Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 20 Jun 2021 13:14:12 -0700 Subject: github: deploy to fly.io instead of GH pages --- users/fcuny/blog/.github/workflows/gh-pages.yml | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/.github/workflows/gh-pages.yml b/users/fcuny/blog/.github/workflows/gh-pages.yml index 70e9ca8..bf3398a 100644 --- a/users/fcuny/blog/.github/workflows/gh-pages.yml +++ b/users/fcuny/blog/.github/workflows/gh-pages.yml @@ -7,24 +7,12 @@ on: jobs: deploy: - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - with: - submodules: true # Fetch Hugo themes (true OR recursive) - fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod - - name: Setup Hugo - uses: peaceiris/actions-hugo@v2 - with: - hugo-version: 'latest' - # extended: true - - - name: Build - run: hugo --minify - - - name: Deploy - uses: peaceiris/actions-gh-pages@v3 + uses: superfly/flyctl-actions@master + env: + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./docs + args: "deploy" -- cgit 1.4.1 From 4389dc08721d65c827b4a59167bb78f1c0459b28 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Mon, 19 Jul 2021 18:58:53 -0700 Subject: hugo: TLS by default --- users/fcuny/blog/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/config.toml b/users/fcuny/blog/config.toml index 532ff03..b3a150a 100644 --- a/users/fcuny/blog/config.toml +++ b/users/fcuny/blog/config.toml @@ -1,4 +1,4 @@ -baseURL = "http://fcuny.net/" +baseURL = "https://fcuny.net/" languageCode = "en-us" title = "Franck's rambling" publishDir = "docs" -- cgit 1.4.1 From 66d58fa4b4c5e7ef88fc3a005c5a29e74dd57b2d Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Thu, 5 Aug 2021 11:29:27 -0700 Subject: build: add Dockerfile The Dockerfile used by fly is relying on an older version of hugo ([1]). We can use a newer version and provide our own setup, and configure with the flags we want (e.g. promote to HTTS automatically). [1] https://github.com/superfly/flyctl/blob/3eb204909fbecd5fd2b1ba4517cdbce2abd9f74a/internal/build/imgsrc/builtins/defaultbuiltins.go#L89 --- users/fcuny/blog/Dockerfile | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 users/fcuny/blog/Dockerfile (limited to 'users/fcuny') diff --git a/users/fcuny/blog/Dockerfile b/users/fcuny/blog/Dockerfile new file mode 100644 index 0000000..5e2b55a --- /dev/null +++ b/users/fcuny/blog/Dockerfile @@ -0,0 +1,7 @@ +FROM klakegg/hugo:0.83.1-ext-alpine-onbuild AS hugo + +FROM pierrezemb/gostatic + +COPY --from=hugo /target /srv/http/ + +CMD ["-port", "8080" , "-https-promote"] -- cgit 1.4.1 From dde5e064c966d6ac1266b32e4a6673d51c7053b1 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Thu, 5 Aug 2021 11:42:21 -0700 Subject: build: add a Makefile Add a Makefile to take care of most common operations (build, deploy, etc). --- users/fcuny/blog/Makefile | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 users/fcuny/blog/Makefile (limited to 'users/fcuny') diff --git a/users/fcuny/blog/Makefile b/users/fcuny/blog/Makefile new file mode 100644 index 0000000..0276958 --- /dev/null +++ b/users/fcuny/blog/Makefile @@ -0,0 +1,29 @@ +DOCKER := DOCKER_BUILDKIT=1 docker +DOCKER_BUILD_ARGS := +DOCKER_IMAGE := fcuny/fcuny.net +DOCKER_IMAGE_REF := $(shell git rev-parse HEAD) +DOCKERFILE := Dockerfile +PROJECT_DIR := $(realpath $(CURDIR)) + +.PHONY: server deploy docker-build docker-run + +server: + @echo "Running hugo server ..." + hugo server + +deploy: + @echo "Deploying to fly ..." + flyctl deploy \ + --build-arg IMAGE_REF=$(DOCKER_IMAGE_REF) + +docker-build: + @echo "Building Docker image ..." + $(DOCKER) build $(DOCKER_BUILD_ARGS) \ + --tag "${DOCKER_IMAGE}:${DOCKER_IMAGE_REF}" \ + --build-arg IMAGE_REF=$(DOCKER_IMAGE_REF) \ + --file "$(DOCKERFILE)" \ + "$(PROJECT_DIR)" + +docker-run: docker-build + @echo "Running Docker image ..." + $(DOCKER) run -ti --rm -p 8080:8080 $(DOCKER_IMAGE) -- cgit 1.4.1 From 263b5b43f03e70403b4ea451710a08525be9c21c Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Thu, 5 Aug 2021 11:42:49 -0700 Subject: hugo: enable git information again Now that we're using a more recent version of the Docker image for hugo that comes with git, we can enable again git information. --- users/fcuny/blog/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/config.toml b/users/fcuny/blog/config.toml index b3a150a..d600506 100644 --- a/users/fcuny/blog/config.toml +++ b/users/fcuny/blog/config.toml @@ -2,7 +2,7 @@ baseURL = "https://fcuny.net/" languageCode = "en-us" title = "Franck's rambling" publishDir = "docs" -enableGitInfo = false +enableGitInfo = true [params] homeText = "A collection of notes" -- cgit 1.4.1 From 30e723d3c419fe527a777951e758862ed17665fb Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Thu, 5 Aug 2021 11:52:50 -0700 Subject: blog: add humans.txt See humanstxt.org for more information. --- users/fcuny/blog/layouts/partials/head.html | 1 + users/fcuny/blog/static/humans.txt | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 users/fcuny/blog/static/humans.txt (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/partials/head.html b/users/fcuny/blog/layouts/partials/head.html index f41eb04..39ef8aa 100644 --- a/users/fcuny/blog/layouts/partials/head.html +++ b/users/fcuny/blog/layouts/partials/head.html @@ -7,6 +7,7 @@ {{ $css := "/css/custom.css" }} + diff --git a/users/fcuny/blog/static/humans.txt b/users/fcuny/blog/static/humans.txt new file mode 100644 index 0000000..d2c9d47 --- /dev/null +++ b/users/fcuny/blog/static/humans.txt @@ -0,0 +1,10 @@ +/* TEAM */ +Author: Franck Cuny +Contact: franck [at] fcuny.net +Twitter: @franckcuny +Location: Berkeley, CA + +/* SITE */ +CA: Let's Encrypt +Host: Fly.io +Serving: Linux, Go -- cgit 1.4.1 From 76eca3b5c9237b6f748a6f8eefc90e5272114dbe Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Thu, 5 Aug 2021 11:55:40 -0700 Subject: blog: add SSH public keys --- users/fcuny/blog/layouts/index.html | 1 + users/fcuny/blog/static/ssh.pub.sig | 1 + 2 files changed, 2 insertions(+) create mode 100644 users/fcuny/blog/static/ssh.pub.sig (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/index.html b/users/fcuny/blog/layouts/index.html index f7581ff..100a77f 100644 --- a/users/fcuny/blog/layouts/index.html +++ b/users/fcuny/blog/layouts/index.html @@ -7,6 +7,7 @@
  • Email: franck@fcuny.net
  • GitHub: @fcuny
  • Twitter: @franckcuny
  • +
  • Keys: SSH public keys

I'm currently working as a Site Reliability Engineer at Twitter, on the Compute team.

diff --git a/users/fcuny/blog/static/ssh.pub.sig b/users/fcuny/blog/static/ssh.pub.sig new file mode 100644 index 0000000..808d3ad --- /dev/null +++ b/users/fcuny/blog/static/ssh.pub.sig @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC1rWKrdSHxlAZnRv1F5jUsHgXSNmr1KzllWEn+JqA7p3zxmSEPBbfIUGxSzkFIQrSbKizJLdH6hGA8DcIm+e+ldQ2RYOdiYBxIkPm+aHB6dw7QGNbnSSdkr9gKThy65j0YOOcmuDExjqxfq6O/8AVstmPH36sUXEIks5F/+WiF+5ehzoJVFqClB1di6w1lml86d0ShrUacgM/ieFPe1vKrzW8ZOM+LaUoGWBTLla1y6UkIqnb7OinmgPu6QAzF6GA7tYJMoHkyV7Axzc2j1/VxVIrUrfY4b0k8lGAzi2GfByq+fXEHzePbaqi8Cy8Trn9eN/ls1WBMUQfSChQi3tM2Vx2BuiOpx/QkXsdgqwe7bTCijcQS7GoREL1qd8tR9sWWd4WMPUiC9kmzvyja5F39xHPgm0A5MtYY7GvQaUPbtBc6g8YuFLLnkqFVEKHSLFiGYP5jIDNvMd5rSSsBUrepCIzWdpprwnKxAjebw5Cyl5p/0MY2zppQRW7AZXehQa7Bv+OClbutEjBa+ioeUxBhezu2rB61XSenTbbUVB5DncD8ceD5AbL9aFz/Bcw6q0kAOGmR1G1MOLgxVHlqcnI5x0E1K2WMKWgQb+1BMek1p5+l3xWNDF4URhLqLupnP5CMrK9ifBOe/76zqyMVrA/mc6tNC58KHhME1IynC1zaLw== franck@fcuny.net -- cgit 1.4.1 From 71247b94c501b20ede60ae8952546f088bfa56a8 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Thu, 5 Aug 2021 12:00:07 -0700 Subject: blog: update description --- users/fcuny/blog/layouts/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/index.html b/users/fcuny/blog/layouts/index.html index 100a77f..1b63249 100644 --- a/users/fcuny/blog/layouts/index.html +++ b/users/fcuny/blog/layouts/index.html @@ -10,6 +10,6 @@
  • Keys: SSH public keys
  • -

    I'm currently working as a Site Reliability Engineer at Twitter, on the Compute team.

    +

    I'm currently working as an Engineer at Twitter, on the Compute team.

    {{ end }} -- cgit 1.4.1 From f7b02cb5f5c543ae9fb3d7749663ea4fd8037a6b Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Thu, 5 Aug 2021 12:53:13 -0700 Subject: css: bigger font and highlight colors Increase the font size and change some of the colors used for highlighting code. --- users/fcuny/blog/layouts/partials/head.html | 2 ++ users/fcuny/blog/static/css/custom.css | 22 ++++++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/partials/head.html b/users/fcuny/blog/layouts/partials/head.html index 39ef8aa..7de4fd4 100644 --- a/users/fcuny/blog/layouts/partials/head.html +++ b/users/fcuny/blog/layouts/partials/head.html @@ -9,6 +9,8 @@ + + diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index 18c9c41..4173138 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -4,9 +4,9 @@ *, *:before, *:after { box-sizing: border-box; } body { - background-color: #ffffff; - line-height: 1.5rem; - font-size: 16px; + background-color: #fffff8; + line-height: 1.8rem; + font-size: 1.3em; font-family: "Roboto Slab", sans-serif; color: #000; padding: 2rem; @@ -43,11 +43,21 @@ span.published, span.updated { } code.verbatim { - background-color: #eeeeee; + background-color: #fffff8; +} + +.highlight pre { + background-color: #fffff8 !important; +} + +.highlight { + padding: 5px; + border-radius: 5px; + border: 1px solid #eee; } pre { - padding: 1rem 2rem; + padding: 0.3rem 0.3rem; margin: 0; font-size: 16px; font-family: 'Source Code Pro', monospace; @@ -55,7 +65,7 @@ pre { } .tags { - background-color: #eeeeee; + /* background-color: #eeeeee; */ border-radius:8px; padding:0 .5rem; font-size: 90%; -- cgit 1.4.1 From 823139e85dfb0294d39f53cde8c1c47a841feabe Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sat, 14 Aug 2021 13:08:02 -0700 Subject: css: reduce the size of the font --- users/fcuny/blog/static/css/custom.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index 4173138..08a7c0a 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -6,7 +6,7 @@ body { background-color: #fffff8; line-height: 1.8rem; - font-size: 1.3em; + font-size: 1em; font-family: "Roboto Slab", sans-serif; color: #000; padding: 2rem; -- cgit 1.4.1 From 1e73ec0df06699f469de35352081a16e77409175 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sat, 14 Aug 2021 13:08:25 -0700 Subject: blog: add link for containerd-to-vm code --- users/fcuny/blog/content/notes/containerd-to-firecracker.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/content/notes/containerd-to-firecracker.org b/users/fcuny/blog/content/notes/containerd-to-firecracker.org index fd41b1d..8ff268c 100644 --- a/users/fcuny/blog/content/notes/containerd-to-firecracker.org +++ b/users/fcuny/blog/content/notes/containerd-to-firecracker.org @@ -14,7 +14,7 @@ They describe the process as follow: 6. Create a TAP device and configure it 7. Hand it off to Firecracker and boot that thing -That's pretty detailed, and I'm curious how difficult it is to implement this. I've been meaning to look into Firecracker for a while and into containers'd API, so this is a perfect opportunity to get started. +That's pretty detailed, and I'm curious how difficult it is to implement this. I've been meaning to look into Firecracker for a while and into containers'd API, so this is a perfect opportunity to get started. The code is available [[https://git.fcuny.net/fcuny/containerd-to-vm][here]]. * #1 Pull a container from a registry with =containerd= =containerd= has a pretty [[https://pkg.go.dev/github.com/containerd/containerd][detailed documentation]]. From the main page we can see the following example to create a client. -- cgit 1.4.1 From afdc1e2b3db0577b802048ea80bea7da0f6424e5 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sat, 14 Aug 2021 13:17:23 -0700 Subject: blog: replace github with git.fcuny.net --- users/fcuny/blog/layouts/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/index.html b/users/fcuny/blog/layouts/index.html index 1b63249..b2f232d 100644 --- a/users/fcuny/blog/layouts/index.html +++ b/users/fcuny/blog/layouts/index.html @@ -5,7 +5,7 @@ -- cgit 1.4.1 From c9ae2f1b2ef43d288d370181b9e069e0ab1cd547 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 15 Aug 2021 13:42:51 -0700 Subject: CSS: use a class for the menu We will have more use of the tag `nav` and we will need different styles for it. --- users/fcuny/blog/layouts/partials/header.html | 2 +- users/fcuny/blog/static/css/custom.css | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/partials/header.html b/users/fcuny/blog/layouts/partials/header.html index f918823..508e259 100644 --- a/users/fcuny/blog/layouts/partials/header.html +++ b/users/fcuny/blog/layouts/partials/header.html @@ -1,5 +1,5 @@
    -
    +{{ if .Params.toc }} +
    + Table of Contents + {{ .TableOfContents }} +
    +{{ end }} + {{ .Content }} {{ end }} diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index b4e37bc..8f776d7 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -140,3 +140,15 @@ nav.menu a.menu-active:hover { nav.menu a.menu-active { color: #007d9c; } + +.toc { + border: 1px solid black; + padding: 1rem; + margin-top: 1rem; + color: black; +} + +.toc a, +.toc a.visited { + color: black; +} -- cgit 1.4.1 From d54131c01237520fec2c718ba353675553b0ae43 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 15 Aug 2021 15:14:02 -0700 Subject: CSS: make the content more readable The Roboto Slab font is hard to read (at least for me). Switch to Droid Sans and make the text a bit smaller. Change the background of the page to white (again), and change the background color for the code snippets. Add text decoration for headlines (similar to org-bullet). --- users/fcuny/blog/static/css/custom.css | 39 +++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 15 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index 8f776d7..1113707 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -1,13 +1,12 @@ -@import url('https://fonts.googleapis.com/css2?family=Roboto+Slab&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap'); *, *:before, *:after { box-sizing: border-box; } body { - background-color: #fffff8; - line-height: 1.8rem; - font-size: 1em; - font-family: "Roboto Slab", sans-serif; + background-color: #ffffff; + line-height: 1.4rem; + font-size: 16px; + font-family: 'Droid Sans', sans-serif; color: #000; padding: 2rem; } @@ -25,14 +24,22 @@ a { p { color: #1a1a19; } -h1 { - line-height: normal; +h1:before { + content: '◉'; +} +h2:before { + content: '○'; +} +h3:before { + content: '✸'; +} +h4:before { + content: '✿'; } h2 { margin-top: 2rem; - line-height: 1.4em; - border-bottom-color: #000000; + border-bottom-color: #eee; border-bottom-style: solid; border-bottom-width: 0.8px; } @@ -43,15 +50,18 @@ span.published, span.updated { } code.verbatim { - background-color: #fffff8; + background-color: #f7f7f7; + white-space: nowrap; + border-radius: 2px; + font-size: 90%; + padding: 2px 2px; } .highlight pre { - background-color: #fffff8 !important; + background-color: #f7f7f7 !important; } .highlight { - padding: 5px; border-radius: 5px; border: 1px solid #eee; } @@ -59,13 +69,12 @@ code.verbatim { pre { padding: 0.3rem 0.3rem; margin: 0; - font-size: 16px; + font-size: 14px; font-family: 'Source Code Pro', monospace; overflow-x: auto; } .tags { - /* background-color: #eeeeee; */ border-radius:8px; padding:0 .5rem; font-size: 90%; @@ -82,6 +91,7 @@ pre { table { border: 1px solid black; + border-radius: 2px; width: 100%; border-spacing: 15px; border-collapse: collapse; @@ -109,7 +119,6 @@ nav.menu { justify-content: flex-end; padding-left: 1em; margin: 0 auto; - line-height: 0.2rem; } nav.menu ul { -- cgit 1.4.1 From 1bc594f88a7ed696ce2d3be47c6423331043f225 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 15 Aug 2021 15:15:40 -0700 Subject: layout: don't use header tag in list --- users/fcuny/blog/layouts/partials/postlist.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/partials/postlist.html b/users/fcuny/blog/layouts/partials/postlist.html index 28fd9b2..e124482 100644 --- a/users/fcuny/blog/layouts/partials/postlist.html +++ b/users/fcuny/blog/layouts/partials/postlist.html @@ -4,7 +4,7 @@ {{ range .Pages.ByDate }}
  • {{ end }} -- cgit 1.4.1 From c971af7cbe14e2cc587dfe3a5b512ba1ba0dad48 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 15 Aug 2021 15:16:01 -0700 Subject: blog: add tags to firecracker notes --- users/fcuny/blog/content/notes/containerd-to-firecracker.org | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/content/notes/containerd-to-firecracker.org b/users/fcuny/blog/content/notes/containerd-to-firecracker.org index 8ff268c..554771d 100644 --- a/users/fcuny/blog/content/notes/containerd-to-firecracker.org +++ b/users/fcuny/blog/content/notes/containerd-to-firecracker.org @@ -1,6 +1,7 @@ #+TITLE: containerd to firecracker #+DATE: <2021-05-15 Sat> -#+TAGS[]: linux, firecracker, containerd +#+TAGS[]: linux firecracker containerd go +#+toc: t fly.io had an [[https://fly.io/blog/docker-without-docker/][interesting article]] about how they use docker images to create VMs for =firecracker=. -- cgit 1.4.1 From f8ceff1bb8c86a5d1ce05bf1fdcf05c94fe09ea3 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 15 Aug 2021 15:16:13 -0700 Subject: blog: working with go - initial content This note captures things that are useful when working with go for me. --- users/fcuny/blog/content/notes/working-with-go.org | 264 +++++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 users/fcuny/blog/content/notes/working-with-go.org (limited to 'users/fcuny') diff --git a/users/fcuny/blog/content/notes/working-with-go.org b/users/fcuny/blog/content/notes/working-with-go.org new file mode 100644 index 0000000..e00f635 --- /dev/null +++ b/users/fcuny/blog/content/notes/working-with-go.org @@ -0,0 +1,264 @@ +#+TITLE: Working with Go +#+DATE: <2021-08-05 Thu> +#+TAGS[]: go emacs +#+toc: t + +/This document assumes go version >= 1.16/. + +* Go Modules +[[https://blog.golang.org/using-go-modules][Go modules]] have been added in 2019 with Go 1.11. A number of changes were introduced with [[https://blog.golang.org/go116-module-changes][Go 1.16]]. This document is a reference for me so that I can find answers to things I keep forgetting. +** Creating a new module +To create a new module, run =go mod init golang.fcuny.net/m=. This will create two files: =go.mod= and =go.sum=. + +In the =go.mod= file you'll find: +- the module import path (prefixed with =module=) +- the list of dependencies (within =require=) +- the version of go to use for the module +** Versioning +To bump the version of a module: +#+begin_src sh +$ git tag v1.2.3 +$ git push --tags +#+end_src + +Then as a user: +#+begin_src sh +$ go get -d golang.fcuny.net/m@v1.2.3 +#+end_src +** Updating dependencies +To update the dependencies, run =go mod tidy= +** Editing a module +If you need to modify a module, you can check out the module in your workspace (=git clone =). + +Edit the =go.mod= file to add +#+begin_src go +replace => +#+end_src + +Then modify the code of the module and the next time you compile the project, the cloned module will be used. + +This is particularly useful when trying to debug an issue with an external module. +** Vendor-ing modules +It's still possible to vendor modules by running =go mod vendor=. This can be useful in the case of a CI setup that does not have access to internet. +** Proxy +As of version 1.13, the variable =GOPROXY= defaults to =https://proxy.golang.org,direct= (see [[https://github.com/golang/go/blob/c95464f0ea3f87232b1f3937d1b37da6f335f336/src/cmd/go/internal/cfg/cfg.go#L269][here]]). As a result, when running something like =go get golang.org/x/tools/gopls@latest=, the request goes through the proxy. + +There's a number of ways to control the behavior, they are documented [[https://golang.org/ref/mod#private-modules][here]]. + +There's a few interesting things that can be done when using the proxy. There's a few special URLs (better documentation [[https://golang.org/ref/mod#goproxy-protocol][here]]): +| path | description | +|-----------------------+------------------------------------------------------------------------------------------| +| $mod/@v/list | Returns the list of known versions - there's one version per line and it's in plain text | +| $mod/@v/$version.info | Returns metadata about a version in JSON format | +| $mod/@v/$version.mod | Returns the =go.mod= file for that version | + +For example, looking at the most recent versions for =gopls=: +#+begin_src sh +; curl -s -L https://proxy.golang.org/golang.org/x/tools/gopls/@v/list|sort -r|head +v0.7.1-pre.2 +v0.7.1-pre.1 +v0.7.1 +v0.7.0-pre.3 +v0.7.0-pre.2 +v0.7.0-pre.1 +v0.7.0 +v0.6.9-pre.1 +v0.6.9 +v0.6.8-pre.1 +#+end_src + +Let's check the details for the most recent version +#+begin_src sh +; curl -s -L https://proxy.golang.org/golang.org/x/tools/gopls/@v/list|sort -r|head +v0.7.1-pre.2 +v0.7.1-pre.1 +v0.7.1 +v0.7.0-pre.3 +v0.7.0-pre.2 +v0.7.0-pre.1 +v0.7.0 +v0.6.9-pre.1 +v0.6.9 +v0.6.8-pre.1 +#+end_src + +And let's look at the content of the =go.mod= for that version too: +#+begin_src sh +; curl -s -L https://proxy.golang.org/golang.org/x/tools/gopls/@v/v0.7.1-pre.2.mod +module golang.org/x/tools/gopls + +go 1.17 + +require ( + github.com/BurntSushi/toml v0.3.1 // indirect + github.com/google/go-cmp v0.5.5 + github.com/google/safehtml v0.0.2 // indirect + github.com/jba/templatecheck v0.6.0 + github.com/sanity-io/litter v1.5.0 + github.com/sergi/go-diff v1.1.0 + golang.org/x/mod v0.4.2 + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect + golang.org/x/sys v0.0.0-20210510120138-977fb7262007 + golang.org/x/text v0.3.6 // indirect + golang.org/x/tools v0.1.6-0.20210802203754-9b21a8868e16 + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + honnef.co/go/tools v0.2.0 + mvdan.cc/gofumpt v0.1.1 + mvdan.cc/xurls/v2 v2.2.0 +) +#+end_src +* Tooling +** LSP +=gopls= is the default implementation of the language server protocol maintained by the Go team. To install the latest version, run =go install golang.org/x/tools/gopls@latest= +** =staticcheck= +[[https://staticcheck.io/][=staticcheck=]] is a great tool to run against your code to find issues. To install the latest version, run =go install honnef.co/go/tools/cmd/staticcheck@latest=. +* Emacs integration +** =go-mode= +[[https://github.com/dominikh/go-mode.el][This is the mode]] to install to get syntax highlighting (mostly). +** Integration with LSP +Emacs has a pretty good integration with LSP. +https://geeksocket.in/posts/emacs-lsp-go/ +*** =lsp-mode= +[[src:https://github.com/emacs-lsp/lsp-mode][This is the main mode to install]]. It provides the integration with LSP. + +I've configured the mode like this: +#+begin_src elisp +(use-package lsp-mode + :ensure t + :commands (lsp lsp-deferred) + :diminish lsp-mode + :hook ((go-mode . lsp-deferred) + (lsp-mode . (lambda() (let ((lsp-keymap-prefix "C-c l")) + (lsp-enable-which-key-integration))))) + :config + (define-key lsp-mode-map (kbd "C-c l") lsp-command-map) + (lsp-register-custom-settings + '(("gopls.completeUnimported" t t) + ("gopls.staticcheck" t t))) + :bind + (("C-c l i" . lsp-ui-imenu)) + :custom + (lsp-session-file (expand-file-name "lsp-session-v1" fcuny/path-emacs-var)) + (lsp-enable-snippet nil) + (lsp-signature-doc-lines 5) + (lsp-modeline-diagnostic-scope :workspace) + (lsp-completion-provider :capf) + (lsp-completion-enable t) + (lsp-enable-indentation t) + (lsp-eldoc-render-all t) + (lsp-prefer-flymake nil)) +#+end_src + ++ =C-c l= brings a menu via [[https://github.com/abo-abo/hydra][hydra]] ++ By default it seems that =staticcheck= is not used, so I force it with the =lsp-register-custom-settings= ++ I prefer [[https://www.flycheck.org/en/latest/][flycheck]] +*** =lsp-ui= +This is mostly for UI tweaks. I use the following configuration +#+begin_src elisp +(use-package lsp-ui + :ensure t + :hook (lsp-mode . lsp-ui-mode) + :commands lsp-ui-mode + :custom + (lsp-ui-doc-delay 0.4) + (lsp-ui-doc-enable t) + (lsp-ui-doc-position 'top) + (lsp-ui-doc-include-signature t) + (lsp-ui-peek-enable t) + (lsp-ui-sideline-enable t) + (lsp-ui-imenu-enable t) + (lsp-ui-flycheck-enable t)) + +#+end_src +*** =lsp-ivy= +I use ivy for completion, [[https://github.com/emacs-lsp/lsp-ivy][it provides]] completion based on the current workspace. This is my configuration: +#+begin_src elisp +(use-package lsp-ivy + :ensure t + :commands lsp-ivy-workspace-symbol) +#+end_src +*** =lsp-treemacs= +[[https://github.com/emacs-lsp/lsp-treemacs][It provides]] some nice improvement regarding the UI. This is my configuration: +#+begin_src elisp +(use-package lsp-treemacs + :ensure t + :config + (lsp-treemacs-sync-mode 1)) + +#+end_src +* Profiling +** pprof +[[https://github.com/google/pprof][pprof]] is a tool to visualize performance data. Let's start with the following test: +#+begin_src go +package main + +import ( + "strings" + "testing" +) + +func BenchmarkStringJoin(b *testing.B) { + input := []string{"a", "b"} + for i := 0; i <= b.N; i++ { + r := strings.Join(input, " ") + if r != "a b" { + b.Errorf("want a b got %s", r) + } + } +} +#+end_src + +Let's run a benchmark with ~go test . -bench=. -cpuprofile cpu_profile.out~: +#+begin_src go +goos: linux +goarch: amd64 +pkg: golang.fcuny.net/m +cpu: Intel(R) Core(TM) i3-1005G1 CPU @ 1.20GHz +BenchmarkStringJoin-4 41833486 26.85 ns/op 3 B/op 1 allocs/op +PASS +ok golang.fcuny.net/m 1.327s +#+end_src + +And let's take a look at the profile with =go tool pprof cpu_profile.out= +#+begin_src sh +File: m.test +Type: cpu +Time: Aug 15, 2021 at 3:01pm (PDT) +Duration: 1.31s, Total samples = 1.17s (89.61%) +Entering interactive mode (type "help" for commands, "o" for options) +(pprof) top +Showing nodes accounting for 1100ms, 94.02% of 1170ms total +Showing top 10 nodes out of 41 + flat flat% sum% cum cum% + 240ms 20.51% 20.51% 240ms 20.51% runtime.memmove + 220ms 18.80% 39.32% 320ms 27.35% runtime.mallocgc + 130ms 11.11% 50.43% 450ms 38.46% runtime.makeslice + 110ms 9.40% 59.83% 1150ms 98.29% golang.fcuny.net/m.BenchmarkStringJoin + 110ms 9.40% 69.23% 580ms 49.57% strings.(*Builder).grow (inline) + 110ms 9.40% 78.63% 1040ms 88.89% strings.Join + 70ms 5.98% 84.62% 300ms 25.64% strings.(*Builder).WriteString + 50ms 4.27% 88.89% 630ms 53.85% strings.(*Builder).Grow (inline) + 40ms 3.42% 92.31% 40ms 3.42% runtime.nextFreeFast (inline) + 20ms 1.71% 94.02% 20ms 1.71% runtime.getMCache (inline) +#+end_src + +We can get a breakdown of the data for our module: +#+begin_src sh +(pprof) list golang.fcuny.net +Total: 1.17s +ROUTINE ======================== golang.fcuny.net/m.BenchmarkStringJoin in /home/fcuny/workspace/gobench/app_test.go + 110ms 1.15s (flat, cum) 98.29% of Total + . . 5: "testing" + . . 6:) + . . 7: + . . 8:func BenchmarkStringJoin(b *testing.B) { + . . 9: b.ReportAllocs() + 10ms 10ms 10: input := []string{"a", "b"} + . . 11: for i := 0; i <= b.N; i++ { + 20ms 1.06s 12: r := strings.Join(input, " ") + 80ms 80ms 13: if r != "a b" { + . . 14: b.Errorf("want a b got %s", r) + . . 15: } + . . 16: } + . . 17:} +#+end_src -- cgit 1.4.1 From 6ea3f4a630684196b417d91551f56ab3f8242847 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 15 Aug 2021 15:22:47 -0700 Subject: build: tag the repo after a deploy If the deployment is successful, tag the repository with the version being deployed on fly.io. Don't deploy unless the repository is clean (this is done with the target `worktree-clean`). --- users/fcuny/blog/Makefile | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/Makefile b/users/fcuny/blog/Makefile index 0276958..1275e1b 100644 --- a/users/fcuny/blog/Makefile +++ b/users/fcuny/blog/Makefile @@ -5,16 +5,21 @@ DOCKER_IMAGE_REF := $(shell git rev-parse HEAD) DOCKERFILE := Dockerfile PROJECT_DIR := $(realpath $(CURDIR)) -.PHONY: server deploy docker-build docker-run +.PHONY: server deploy docker-build docker-run worktree-clean server: @echo "Running hugo server ..." hugo server -deploy: +worktree-clean: + git diff --exit-code + git diff --staged --exit-code + +deploy: worktree-clean docker-build @echo "Deploying to fly ..." flyctl deploy \ --build-arg IMAGE_REF=$(DOCKER_IMAGE_REF) + git tag --message $(shell flyctl info -j |jq '.App | "\(.Name)/v\(.Version)"') $(shell flyctl info -j |jq '.App | "\(.Name)/v\(.Version)"') docker-build: @echo "Building Docker image ..." -- cgit 1.4.1 From b667d82b1e01bbdcbeeff6defc483540188856e0 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Mon, 23 Aug 2021 09:15:40 -0700 Subject: CSS: makes the menu more readable Move the title to the left and the menu items to the right. --- users/fcuny/blog/layouts/partials/header.html | 14 ++++---- users/fcuny/blog/static/css/custom.css | 48 ++++++++++++++++++--------- 2 files changed, 39 insertions(+), 23 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/partials/header.html b/users/fcuny/blog/layouts/partials/header.html index 508e259..76e23a2 100644 --- a/users/fcuny/blog/layouts/partials/header.html +++ b/users/fcuny/blog/layouts/partials/header.html @@ -1,15 +1,13 @@
    diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index 1113707..3475d1f 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -115,39 +115,57 @@ blockquote { nav.menu { display: flex; - flex: 2 0px; - justify-content: flex-end; - padding-left: 1em; + justify-content: flex-start; + flex-direction: row; + flex-wrap: nowrap; margin: 0 auto; + font-size: 18px; } -nav.menu ul { +.navigation { display: flex; - list-style-type: none; - margin: 0 + justify-content: flex-end; + flex-direction: row; + flex-wrap: nowrap; + box-sizing: border-box; + flex-basis: auto; + flex-grow: 1; + align-items: center; +} + +.menu-item { + box-sizing: border-box; + font-weight: 400; + padding-right: 8px; } nav.menu a { - padding: 1em; display: inline-block; color: black; - font-family: sans-serif; text-decoration: none; transition: all 75ms ease-in; } -nav.menu a:hover { - color: #fff; - background-color: #007d9c; +.navigation a:hover { + text-decoration: underline; + text-decoration-thickness: 4px; + text-underline-offset:.3rem; + color: #007d9c; } -nav.menu a.menu-active:hover { - color: #fff; - background-color: #007d9c; +a.menu-active:hover { + text-decoration: underline; + text-underline-offset:.3rem; + color: #007d9c; + font-weight: 700; } -nav.menu a.menu-active { +a.menu-active { + text-decoration: underline; + text-underline-offset:.3rem; + text-decoration-thickness: 4px; color: #007d9c; + font-weight: 700; } .toc { -- cgit 1.4.1 From 3a3b604077b62c39165331c45f839b81b1b5423e Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Mon, 23 Aug 2021 09:31:20 -0700 Subject: CSS: rename the class for the tags --- users/fcuny/blog/static/css/custom.css | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index 3475d1f..95f5feb 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -74,10 +74,12 @@ pre { overflow-x: auto; } -.tags { - border-radius:8px; - padding:0 .5rem; - font-size: 90%; +.meta_tags { + border-radius: 8px; + padding: 0 .5rem; + font-size: 80%; + border: 2px solid #eee; + background-color: #eee } .meta_tags a:link, -- cgit 1.4.1 From b03e752a4522209d77d2c153a8bee8601a2808d5 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Mon, 23 Aug 2021 09:32:05 -0700 Subject: CSS: use decoration on headers only for articles Add an element "article" to the single page template, and change the CSS to use the decoration for headers only for that kind of content. Having decoration for all headers is distracting, it's more suited for actual content. We also don't need decoration for h1, only smaller headers. --- users/fcuny/blog/layouts/_default/single.html | 8 ++++++-- users/fcuny/blog/static/css/custom.css | 8 ++++---- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/_default/single.html b/users/fcuny/blog/layouts/_default/single.html index b4c5443..165c568 100644 --- a/users/fcuny/blog/layouts/_default/single.html +++ b/users/fcuny/blog/layouts/_default/single.html @@ -1,5 +1,7 @@ {{ define "main" }} +
    +

    {{ .Title }}

    @@ -18,9 +20,9 @@ {{ if .Params.tags }}
    {{ if eq (len .Params.tags) 1 }} - in tag + tag: {{ else }} - in tags + tags: {{ end }} {{ range $idx, $tag := .Params.tags }} {{ $tag }} @@ -38,4 +40,6 @@ {{ .Content }} +
    + {{ end }} diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index 95f5feb..2d7a36e 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -24,16 +24,16 @@ a { p { color: #1a1a19; } -h1:before { +article.article h2:before { content: '◉'; } -h2:before { +article.article h3:before { content: '○'; } -h3:before { +article.article h4:before { content: '✸'; } -h4:before { +article.article h5:before { content: '✿'; } -- cgit 1.4.1 From 14b26f82f0d3f52f1498b3739cf2c44e03fea23b Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Mon, 23 Aug 2021 09:33:39 -0700 Subject: index: drop the main header It's ugly. --- users/fcuny/blog/layouts/index.html | 2 -- 1 file changed, 2 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/index.html b/users/fcuny/blog/layouts/index.html index b2f232d..f34b21f 100644 --- a/users/fcuny/blog/layouts/index.html +++ b/users/fcuny/blog/layouts/index.html @@ -1,8 +1,6 @@ {{ define "main" }}
    -

    Franck Cuny

    -
    • Email: franck@fcuny.net
    • Git: @fcuny
    • -- cgit 1.4.1 From f845f6360899a9226c8c3a93c0a915ff2735e239 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Mon, 23 Aug 2021 09:33:55 -0700 Subject: CSS: various small fixes --- users/fcuny/blog/static/css/custom.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index 2d7a36e..ba9dddf 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -4,7 +4,7 @@ body { background-color: #ffffff; - line-height: 1.4rem; + line-height: 22px; font-size: 16px; font-family: 'Droid Sans', sans-serif; color: #000; @@ -52,7 +52,7 @@ span.published, span.updated { code.verbatim { background-color: #f7f7f7; white-space: nowrap; - border-radius: 2px; + border-radius: 8px; font-size: 90%; padding: 2px 2px; } -- cgit 1.4.1 From b6edafcfc6433000e41073910d3911d52b148f12 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 24 Aug 2021 19:24:52 -0700 Subject: build: sleep before tagging The last deploy was tagged v13, while the version deployed was 14. It's possible that running `fly info` too quickly after a deploy returns the incorrect version. Adding a `sleep 5` before running the command for git tag. --- users/fcuny/blog/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/Makefile b/users/fcuny/blog/Makefile index 1275e1b..d602b52 100644 --- a/users/fcuny/blog/Makefile +++ b/users/fcuny/blog/Makefile @@ -19,6 +19,7 @@ deploy: worktree-clean docker-build @echo "Deploying to fly ..." flyctl deploy \ --build-arg IMAGE_REF=$(DOCKER_IMAGE_REF) + @sleep 5 git tag --message $(shell flyctl info -j |jq '.App | "\(.Name)/v\(.Version)"') $(shell flyctl info -j |jq '.App | "\(.Name)/v\(.Version)"') docker-build: -- cgit 1.4.1 From 5fcc5d8c61c245b7f08673db76865e23ee77771e Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 24 Aug 2021 19:21:23 -0700 Subject: blog: sort pages in reverse order --- users/fcuny/blog/layouts/partials/postlist.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/partials/postlist.html b/users/fcuny/blog/layouts/partials/postlist.html index e124482..3d5cf04 100644 --- a/users/fcuny/blog/layouts/partials/postlist.html +++ b/users/fcuny/blog/layouts/partials/postlist.html @@ -1,7 +1,7 @@ {{ range .GroupByDate "2006" }}

      {{ .Key }}

        - {{ range .Pages.ByDate }} + {{ range .Pages.ByDate.Reverse }}
      • {{ .Title }} -- cgit 1.4.1 From db2f465e1ffe08cefae90f5390121d2a12477ca5 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 24 Aug 2021 19:21:46 -0700 Subject: blog: git-link and sourcegraph --- .../blog/content/blog/git-link-and-sourcegraph.org | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 users/fcuny/blog/content/blog/git-link-and-sourcegraph.org (limited to 'users/fcuny') diff --git a/users/fcuny/blog/content/blog/git-link-and-sourcegraph.org b/users/fcuny/blog/content/blog/git-link-and-sourcegraph.org new file mode 100644 index 0000000..034f8da --- /dev/null +++ b/users/fcuny/blog/content/blog/git-link-and-sourcegraph.org @@ -0,0 +1,40 @@ +#+TITLE: emacs' git-link and sourcegraph +#+TAGS[]: emacs git +#+DATE: <2021-08-24 Tue> + +I use [[https://sourcegraph.com/][sourcegraph]] for searching code, and I sometimes need to share a link to the source code I'm looking at in a buffer. For this, the package [[https://github.com/sshaw/git-link][=git-link=]] is great. + +To integrate sourcegraph and =git-link=, the [[https://github.com/sshaw/git-link#sourcegraph][documentation]] recommends adding a remote entry named =sourcegraph= in the repository, like this: + +#+begin_src sh +git remote add sourcegraph https://sourcegraph.com/github.com/sshaw/copy-as-format +#+end_src + +The next time you run =M-x git-link= in a buffer, it will use the URL associated with that remote. That's works great, except that now you need to add this for every repository. Instead, for my usage, I came up with the following solution: + +#+begin_src elisp +(use-package git-link + :ensure t + :config + (defun fcuny/get-sg-remote-from-hostname (hostname) + (format "sourcegraph.<$domain>.<$tld>/%s" hostname)) + + (defun fcuny/git-link-work-sourcegraph (hostname dirname filename branch commit start end) + (let ((sg-base-url (fcuny/get-sg-remote-from-hostname hostname))) + (git-link-sourcegraph sg-base-url dirname filename branch commit start end))) + + (defun fcuny/git-link-commit-work-sourcegraph (hostname dirname commit) + (let ((sg-base-url (fcuny/get-sg-remote-from-hostname hostname))) + (git-link-commit-sourcegraph sg-base-url dirname commit))) + + (add-to-list 'git-link-remote-alist '("twitter" fcuny/git-link-work-sourcegraph)) + (add-to-list 'git-link-commit-remote-alist '("twitter" fcuny/git-link-commit-work-sourcegraph)) + + (setq git-link-open-in-browser 't)) +#+end_src + +We use different domains to host various git repositories at work (e.g. =git.$work=, =gitfoo.$work=, etc). Each of them map to a different URI for sourcegraph (e.g. =sourcegraph.$work/gitfoo=). + +=git-link-commit-remote-alist= is an [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Association-Lists.html][association list]] that takes a regular expression and a function. The custom function receives the hostname for the remote repository, which is then used to generate the URI for our sourcegraph instance. I then call =git-link-sourcegraph= replacing the hostname with the URI for sourcegraph. + +Now I can run =M-x git-link= in any repository where the host for the origin git repository matches =twitter= without having to setup the custom remote first. -- cgit 1.4.1 From 0aba5b254e691aab6eaa96c69ffc8f189ed87b4c Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Thu, 26 Aug 2021 17:35:15 -0700 Subject: static: add profile picture --- users/fcuny/blog/static/profile.jpg | Bin 0 -> 895450 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 users/fcuny/blog/static/profile.jpg (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/profile.jpg b/users/fcuny/blog/static/profile.jpg new file mode 100644 index 0000000..5417f13 Binary files /dev/null and b/users/fcuny/blog/static/profile.jpg differ -- cgit 1.4.1 From 2bc21a0cb86dc06c8366a6ae72b84a2a95188af4 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Thu, 9 Sep 2021 17:28:29 -0700 Subject: blog: update elisp for git/sourcegraph --- .../fcuny/blog/content/blog/git-link-and-sourcegraph.org | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/content/blog/git-link-and-sourcegraph.org b/users/fcuny/blog/content/blog/git-link-and-sourcegraph.org index 034f8da..3ab5f4b 100644 --- a/users/fcuny/blog/content/blog/git-link-and-sourcegraph.org +++ b/users/fcuny/blog/content/blog/git-link-and-sourcegraph.org @@ -15,13 +15,22 @@ The next time you run =M-x git-link= in a buffer, it will use the URL associated #+begin_src elisp (use-package git-link :ensure t + :after magit + :bind (("C-c g l" . git-link) + ("C-c g a" . git-link-commit)) :config (defun fcuny/get-sg-remote-from-hostname (hostname) (format "sourcegraph.<$domain>.<$tld>/%s" hostname)) - (defun fcuny/git-link-work-sourcegraph (hostname dirname filename branch commit start end) - (let ((sg-base-url (fcuny/get-sg-remote-from-hostname hostname))) - (git-link-sourcegraph sg-base-url dirname filename branch commit start end))) + (defun fcuny/git-link-work-sourcegraph (hostname dirname filename _branch commit start end) + ;;; For a given repository, build the proper link for sourcegraph. + ;;; Use the default branch of the repository instead of the + ;;; current one (we might be on a feature branch that is not + ;;; available on the remote). + (require 'magit-branch) + (let ((sg-base-url (fcuny/get-sg-remote-from-hostname hostname)) + (main-branch (magit-main-branch))) + (git-link-sourcegraph sg-base-url dirname filename main-branch commit start end))) (defun fcuny/git-link-commit-work-sourcegraph (hostname dirname commit) (let ((sg-base-url (fcuny/get-sg-remote-from-hostname hostname))) -- cgit 1.4.1 From 1c620dc4f9dcd5d90f6954c4adae07d8cae19ee7 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Thu, 9 Sep 2021 18:03:00 -0700 Subject: build: get the proper version for tagging We were evaluating the version of the app when the rule was evaluated, while we need to get the version after we run `flyctl deploy`. Since we're tagging a release, let's also annotate the tag. Remove the `--build-arg` argument to `flyct deploy` since it's being ignored (same with `docker build`). Closes #1. --- users/fcuny/blog/Makefile | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/Makefile b/users/fcuny/blog/Makefile index d602b52..b117922 100644 --- a/users/fcuny/blog/Makefile +++ b/users/fcuny/blog/Makefile @@ -17,16 +17,13 @@ worktree-clean: deploy: worktree-clean docker-build @echo "Deploying to fly ..." - flyctl deploy \ - --build-arg IMAGE_REF=$(DOCKER_IMAGE_REF) - @sleep 5 - git tag --message $(shell flyctl info -j |jq '.App | "\(.Name)/v\(.Version)"') $(shell flyctl info -j |jq '.App | "\(.Name)/v\(.Version)"') + flyctl deploy + @git tag -a --message $$(flyctl info -j |jq -r '.App | "fcuny.net/v\(.Version)"') $$(flyctl info -j |jq -r '.App | "fcuny.net/v\(.Version)"') docker-build: @echo "Building Docker image ..." $(DOCKER) build $(DOCKER_BUILD_ARGS) \ --tag "${DOCKER_IMAGE}:${DOCKER_IMAGE_REF}" \ - --build-arg IMAGE_REF=$(DOCKER_IMAGE_REF) \ --file "$(DOCKERFILE)" \ "$(PROJECT_DIR)" -- cgit 1.4.1 From c3fec6c580ca227ad9108e8869ac0578862eabda Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sat, 2 Oct 2021 07:40:56 -0700 Subject: static: add ssh-key from desktop --- users/fcuny/blog/static/ssh.pub.sig | 1 + 1 file changed, 1 insertion(+) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/ssh.pub.sig b/users/fcuny/blog/static/ssh.pub.sig index 808d3ad..88f4f3e 100644 --- a/users/fcuny/blog/static/ssh.pub.sig +++ b/users/fcuny/blog/static/ssh.pub.sig @@ -1 +1,2 @@ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC1rWKrdSHxlAZnRv1F5jUsHgXSNmr1KzllWEn+JqA7p3zxmSEPBbfIUGxSzkFIQrSbKizJLdH6hGA8DcIm+e+ldQ2RYOdiYBxIkPm+aHB6dw7QGNbnSSdkr9gKThy65j0YOOcmuDExjqxfq6O/8AVstmPH36sUXEIks5F/+WiF+5ehzoJVFqClB1di6w1lml86d0ShrUacgM/ieFPe1vKrzW8ZOM+LaUoGWBTLla1y6UkIqnb7OinmgPu6QAzF6GA7tYJMoHkyV7Axzc2j1/VxVIrUrfY4b0k8lGAzi2GfByq+fXEHzePbaqi8Cy8Trn9eN/ls1WBMUQfSChQi3tM2Vx2BuiOpx/QkXsdgqwe7bTCijcQS7GoREL1qd8tR9sWWd4WMPUiC9kmzvyja5F39xHPgm0A5MtYY7GvQaUPbtBc6g8YuFLLnkqFVEKHSLFiGYP5jIDNvMd5rSSsBUrepCIzWdpprwnKxAjebw5Cyl5p/0MY2zppQRW7AZXehQa7Bv+OClbutEjBa+ioeUxBhezu2rB61XSenTbbUVB5DncD8ceD5AbL9aFz/Bcw6q0kAOGmR1G1MOLgxVHlqcnI5x0E1K2WMKWgQb+1BMek1p5+l3xWNDF4URhLqLupnP5CMrK9ifBOe/76zqyMVrA/mc6tNC58KHhME1IynC1zaLw== franck@fcuny.net +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDg2P92WEDsI2mn2QEk1uSg9MKbj7JgE3pEfI6bWo5fbcnUbVGGZxafK0e7rnSfgWHHyhVeH8W4fQfPb+Iyt/9GLkKEq3aqShVEq+h2FXu7iqdrsANp27UnanuHuL2MzQY041jAiqrmJUBzCedJfnmlydMoo0TdK2Hxzu3cLjaI0VhEySo8c/NKuUB6uIdfuA8dkvIdP2O0owpLoKOGDdsDTedhGiN+mQgB+Z2+oYM4XOVmcMY6/f2cxXRBCkktcy9s451NqhjmsVB/L1n1GjJlOk+mQ6wGjR7KN7bgJtBC2sE/WuiZL+pmOlu3dF9vLyWw7iPHj7YvLlK6gztBHZT2v694Thqd9yb/ESOFfyrcujZu0qkRhjPYOz7VJC9F9PmTIVW6Zk4kknQzh9pmKWJiDNZEaQ88cXGn+HBj9aZ/fj3h6TyowtLZkXWebNcUHFMquuTMpJigFq+bSvus5Ad+v5L185CNa/9o3P1TNAft4YF3IR0WfJ08aNcFBYkiOXivpuTmbMzuRKUQ/5dhAlOuqTSzDDEFa6Q9MMo2oorNcZhjrfKq/T7gKXKqG8DuWNGKsM1ZduduCjunuWJw9SjUHVEwW2NtNHcvRWP19HFy/+T5rWDBEUUSYQba34xnvMRa9NZLeqGC+korXCUjxjQEM8aFpCUmqdwY6QBgpyGAbw== franck@fcuny.net -- cgit 1.4.1 From 36e2de74e581d7efac8e20fc5e5a7622d7030340 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Thu, 21 Oct 2021 19:32:40 -0700 Subject: build: be explicit about the image to use If we're not explicit, we're trying to run the image tagged `latest', but there's no image with that tag. --- users/fcuny/blog/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/Makefile b/users/fcuny/blog/Makefile index b117922..81174c9 100644 --- a/users/fcuny/blog/Makefile +++ b/users/fcuny/blog/Makefile @@ -29,4 +29,4 @@ docker-build: docker-run: docker-build @echo "Running Docker image ..." - $(DOCKER) run -ti --rm -p 8080:8080 $(DOCKER_IMAGE) + $(DOCKER) run -ti --rm -p 8080:8080 "${DOCKER_IMAGE}:${DOCKER_IMAGE_REF}" -- cgit 1.4.1 From 7982756542a81bf311955c76f42eb29404197a4f Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Fri, 12 Nov 2021 17:17:02 -0800 Subject: static: add my resume --- users/fcuny/blog/static/resume.pdf | Bin 0 -> 46184 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 users/fcuny/blog/static/resume.pdf (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/resume.pdf b/users/fcuny/blog/static/resume.pdf new file mode 100644 index 0000000..80b9b79 Binary files /dev/null and b/users/fcuny/blog/static/resume.pdf differ -- cgit 1.4.1 From 5b9e505653edf78e77a9849c0213c2840d872f00 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Fri, 12 Nov 2021 17:25:27 -0800 Subject: resume: update --- users/fcuny/blog/static/resume.pdf | Bin 46184 -> 46970 bytes 1 file changed, 0 insertions(+), 0 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/resume.pdf b/users/fcuny/blog/static/resume.pdf index 80b9b79..123b9ef 100644 Binary files a/users/fcuny/blog/static/resume.pdf and b/users/fcuny/blog/static/resume.pdf differ -- cgit 1.4.1 From a4a18316efcea78efe3eeae15f527eb883391299 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Mon, 6 Dec 2021 17:50:39 -0800 Subject: CSS: drop custom fonts + colors --- users/fcuny/blog/static/css/custom.css | 41 ++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index ba9dddf..4502d70 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -1,12 +1,10 @@ -@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap'); - *, *:before, *:after { box-sizing: border-box; } body { - background-color: #ffffff; + background-color: #fbf1c7; line-height: 22px; - font-size: 16px; - font-family: 'Droid Sans', sans-serif; + font-size: 1.1em; + font-family: monospace; color: #000; padding: 2rem; } @@ -19,10 +17,10 @@ body { a { text-decoration: underline; text-underline-offset:.3rem; - color: #007d9c; + color: #8f3f71; } -p { color: #1a1a19; } +p { color: #282828; } article.article h2:before { content: '◉'; @@ -37,9 +35,13 @@ article.article h5:before { content: '✿'; } +h1, h2, h3, h4, h5 { + font-family: sans-serif; +} + h2 { - margin-top: 2rem; - border-bottom-color: #eee; + margin-top: 1.3rem; + border-bottom-color: #282828; border-bottom-style: solid; border-bottom-width: 0.8px; } @@ -53,7 +55,6 @@ code.verbatim { background-color: #f7f7f7; white-space: nowrap; border-radius: 8px; - font-size: 90%; padding: 2px 2px; } @@ -69,9 +70,10 @@ code.verbatim { pre { padding: 0.3rem 0.3rem; margin: 0; - font-size: 14px; - font-family: 'Source Code Pro', monospace; + font-size: 1.1em; + font-family: monospace; overflow-x: auto; + border: 1px solid #000; } .meta_tags { @@ -98,8 +100,8 @@ table { border-spacing: 15px; border-collapse: collapse; letter-spacing: 1px; - font-family: 'Source Code Pro', monospace; - font-size: 16px; + font-family: monospace; + font-size: 1.1em; text-align: left; } @@ -111,8 +113,9 @@ thead { blockquote { background-color: #fffff0; border-radius: 5px; - padding-left: 5px; font-style: italic; + border-left: 6px solid lightgray; + margin-left: 10.875px; } nav.menu { @@ -121,7 +124,7 @@ nav.menu { flex-direction: row; flex-wrap: nowrap; margin: 0 auto; - font-size: 18px; + font-size: 1.2em; } .navigation { @@ -152,13 +155,13 @@ nav.menu a { text-decoration: underline; text-decoration-thickness: 4px; text-underline-offset:.3rem; - color: #007d9c; + color: #076678; } a.menu-active:hover { text-decoration: underline; text-underline-offset:.3rem; - color: #007d9c; + color: #076678; font-weight: 700; } @@ -166,7 +169,7 @@ a.menu-active { text-decoration: underline; text-underline-offset:.3rem; text-decoration-thickness: 4px; - color: #007d9c; + color: #076678; font-weight: 700; } -- cgit 1.4.1 From f15fc5824ece25e28fc5ce0e50bd949dd10f33cb Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Mon, 6 Dec 2021 17:58:36 -0800 Subject: build: push git branches / tags after deploy After a successful deploy, push all the branches / tags to origin. --- users/fcuny/blog/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/Makefile b/users/fcuny/blog/Makefile index 81174c9..5414dde 100644 --- a/users/fcuny/blog/Makefile +++ b/users/fcuny/blog/Makefile @@ -19,6 +19,8 @@ deploy: worktree-clean docker-build @echo "Deploying to fly ..." flyctl deploy @git tag -a --message $$(flyctl info -j |jq -r '.App | "fcuny.net/v\(.Version)"') $$(flyctl info -j |jq -r '.App | "fcuny.net/v\(.Version)"') + @git push origin --all + @git push origin --tags docker-build: @echo "Building Docker image ..." -- cgit 1.4.1 From e09c70965afc75eb1a3ae02e8bbc88fce562f69d Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Mon, 20 Dec 2021 14:30:49 -0800 Subject: menu: simplify the menu --- users/fcuny/blog/config.toml | 7 +++++++ users/fcuny/blog/layouts/partials/header.html | 12 +++--------- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/config.toml b/users/fcuny/blog/config.toml index d600506..c126d16 100644 --- a/users/fcuny/blog/config.toml +++ b/users/fcuny/blog/config.toml @@ -16,6 +16,13 @@ enableGitInfo = true tags = "/tags/:slug/" [menu] + [[menu.main]] + identifier = "home" + name = "home" + title = "fcuny.net" + url = "/" + weight = 130 + [[menu.main]] identifier = "articles" name = "blog" diff --git a/users/fcuny/blog/layouts/partials/header.html b/users/fcuny/blog/layouts/partials/header.html index 76e23a2..9118a50 100644 --- a/users/fcuny/blog/layouts/partials/header.html +++ b/users/fcuny/blog/layouts/partials/header.html @@ -1,13 +1,7 @@
        -- cgit 1.4.1 From c537016812c435ad4f2e461d0aca33f60aba98a7 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Mon, 20 Dec 2021 14:31:06 -0800 Subject: index: re-organize the main page Add a "contact" header with my information under it. --- users/fcuny/blog/layouts/index.html | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/index.html b/users/fcuny/blog/layouts/index.html index f34b21f..9e15e77 100644 --- a/users/fcuny/blog/layouts/index.html +++ b/users/fcuny/blog/layouts/index.html @@ -1,13 +1,15 @@ {{ define "main" }} -
        - - -

        I'm currently working as an Engineer at Twitter, on the Compute team.

        +

        {{ .Site.Home.Title }}

        + +

        I'm currently working as an Engineer at Twitter, on the Compute team.

        + +

        Contact

        + {{ end }} -- cgit 1.4.1 From b2cf2de7e131af146f1e15a5d106422026062201 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Mon, 20 Dec 2021 14:31:30 -0800 Subject: css: improve the color and fonts --- users/fcuny/blog/static/css/custom.css | 163 ++++++++++----------------------- 1 file changed, 47 insertions(+), 116 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index 4502d70..cbeac27 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -1,77 +1,56 @@ -*, *:before, *:after { box-sizing: border-box; } - body { + font-family: sans-serif; + line-height:1.6; + font-size:18px; + color: #000111; background-color: #fbf1c7; - line-height: 22px; - font-size: 1.1em; - font-family: monospace; - color: #000; - padding: 2rem; -} - -.main { - margin: auto; - max-width: 60rem; -} - -a { - text-decoration: underline; - text-underline-offset:.3rem; - color: #8f3f71; + margin:1em auto; + max-width:750px; + padding:0 0.55em; } -p { color: #282828; } +h1, h2, h3, h4, h5 {line-height:1.2} +h1{margin-top:1em;margin-bottom:0.34em} +h2{margin-top:1.25em;margin-bottom:0.41em} +h3{margin-top:1.5em;margin-bottom:0.5em} -article.article h2:before { - content: '◉'; -} -article.article h3:before { - content: '○'; -} -article.article h4:before { - content: '✸'; -} -article.article h5:before { - content: '✿'; +hr{ + color:#000111; + background-color:#000111; + border:none; + height:2px } -h1, h2, h3, h4, h5 { - font-family: sans-serif; -} - -h2 { - margin-top: 1.3rem; - border-bottom-color: #282828; - border-bottom-style: solid; - border-bottom-width: 0.8px; -} +a {color: #494d7e;} +a:visited {color: #494d7e;} span.published, span.updated { display: center; font-style: oblique; } +code { + font-family: monospace; + font-size: 80%; +} code.verbatim { - background-color: #f7f7f7; - white-space: nowrap; - border-radius: 8px; - padding: 2px 2px; + background-color: #fffff8; } -.highlight pre { - background-color: #f7f7f7 !important; +:not(pre) code{ + padding-left:0.1em; + padding-right:0.1em; + border-radius:2px; } -.highlight { - border-radius: 5px; - border: 1px solid #eee; -} +.highlight pre {background-color: #fffff8 !important} +.highlight {border-radius: 5px} pre { + font-family: monospace; padding: 0.3rem 0.3rem; margin: 0; - font-size: 1.1em; - font-family: monospace; + line-height: 1.1; overflow-x: auto; border: 1px solid #000; } @@ -81,40 +60,40 @@ pre { padding: 0 .5rem; font-size: 80%; border: 2px solid #eee; - background-color: #eee + background-color: #eee; } -.meta_tags a:link, -.meta_tags a:visited { +.meta_tags a:link, .meta_tags a:visited { text-decoration: none; } .meta_date { font-style: italic; + font-size: 80%; } table { - border: 1px solid black; - border-radius: 2px; width: 100%; - border-spacing: 15px; - border-collapse: collapse; - letter-spacing: 1px; - font-family: monospace; - font-size: 1.1em; - text-align: left; + border-spacing: 0px; + outline: none; +} + +th, td{ + padding-left:0.7em; + padding-right:0.7em; + padding-top:0.4em; + padding-bottom:0.4em; } -thead { - background-color: #E0EBF5; - font-weight: bold; +table, th, td { + border:1px solid black; } blockquote { - background-color: #fffff0; + background-color: #fffff8; border-radius: 5px; font-style: italic; - border-left: 6px solid lightgray; + border-left: 6px solid black; margin-left: 10.875px; } @@ -124,63 +103,15 @@ nav.menu { flex-direction: row; flex-wrap: nowrap; margin: 0 auto; - font-size: 1.2em; -} - -.navigation { - display: flex; - justify-content: flex-end; - flex-direction: row; - flex-wrap: nowrap; - box-sizing: border-box; - flex-basis: auto; - flex-grow: 1; - align-items: center; } .menu-item { - box-sizing: border-box; - font-weight: 400; padding-right: 8px; } -nav.menu a { - display: inline-block; - color: black; - text-decoration: none; - transition: all 75ms ease-in; -} - -.navigation a:hover { - text-decoration: underline; - text-decoration-thickness: 4px; - text-underline-offset:.3rem; - color: #076678; -} - -a.menu-active:hover { - text-decoration: underline; - text-underline-offset:.3rem; - color: #076678; - font-weight: 700; -} - -a.menu-active { - text-decoration: underline; - text-underline-offset:.3rem; - text-decoration-thickness: 4px; - color: #076678; - font-weight: 700; -} - .toc { border: 1px solid black; padding: 1rem; margin-top: 1rem; color: black; } - -.toc a, -.toc a.visited { - color: black; -} -- cgit 1.4.1 From 6a6fac903f0bf668803da05ec990b72bb70ceeee Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Wed, 29 Dec 2021 09:11:14 -0800 Subject: RSS: fix the template Generate correctly the content of the RSS feed. I only want the blog articles, not the notes. --- users/fcuny/blog/layouts/index.atom.xml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/index.atom.xml b/users/fcuny/blog/layouts/index.atom.xml index 531e77c..1d73f9b 100644 --- a/users/fcuny/blog/layouts/index.atom.xml +++ b/users/fcuny/blog/layouts/index.atom.xml @@ -1,5 +1,5 @@ - Franck Cuny Website + {{ .Site.Title }} {{ .Permalink }}{{ with .Site.Author.name }} @@ -7,7 +7,8 @@ {{.}}{{ with $.Site.Author.email }} {{.}}{{end}} {{end}} - Hugo -- gohugo.io{{ range where (first 10 (where .Site.Pages "Section" "posts")) "Params.hidden" "ne" "true" }} + Hugo -- gohugo.io + {{ range where (first 10 (where .Site.Pages "Section" "blog")) "Params.hidden" "ne" "true" }} {{ `<![CDATA[` | safeHTML }}{{ .Title }}]]> @@ -18,5 +19,6 @@ {{- $fmt := "2006-01-02T15:04:05-07:00" }} {{ .Date.Format $fmt | safeHTML }} {{ ` - {{ end }} + + {{ end }} -- cgit 1.4.1 From 691b8c2e05a95dc7dc18c240e694b342144b221b Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Wed, 29 Dec 2021 09:11:40 -0800 Subject: layout: add a link to the RSS feed in the menu Specify the weight so that the items in the menu are listed in the order I want. --- users/fcuny/blog/config.toml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/config.toml b/users/fcuny/blog/config.toml index c126d16..6a6f070 100644 --- a/users/fcuny/blog/config.toml +++ b/users/fcuny/blog/config.toml @@ -21,19 +21,28 @@ enableGitInfo = true name = "home" title = "fcuny.net" url = "/" - weight = 130 + weight = 100 [[menu.main]] identifier = "articles" name = "blog" title = "articles" url = "/blog/" + weight = 110 [[menu.main]] identifier = "notes" name = "notes" title = "notes" url = "/notes/" + weight = 120 + + [[menu.main]] + identifier = "RSS" + name = "RSS" + title = "RSS" + url = "/feed.xml" + weight = 130 [markup] [markup.tableOfContents] -- cgit 1.4.1 From 6a74461b8a07c8fe7e5ca4e9d1ef299c56f94d2c Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Wed, 29 Dec 2021 09:19:46 -0800 Subject: config: add author information --- users/fcuny/blog/config.toml | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/config.toml b/users/fcuny/blog/config.toml index 6a6f070..7162180 100644 --- a/users/fcuny/blog/config.toml +++ b/users/fcuny/blog/config.toml @@ -7,6 +7,10 @@ enableGitInfo = true [params] homeText = "A collection of notes" +[author] + name = "Franck Cuny" + email = "franck@fcuny.net" + [taxonomies] tag = "tags" -- cgit 1.4.1 From 83d4b85ef9c77dbc68787ef1a1a789e2f4c9222e Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Wed, 29 Dec 2021 09:12:40 -0800 Subject: blog: article on how to use tailscale + traefik --- .../blog/content/blog/tailscale-docker-https.org | 121 +++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 users/fcuny/blog/content/blog/tailscale-docker-https.org (limited to 'users/fcuny') diff --git a/users/fcuny/blog/content/blog/tailscale-docker-https.org b/users/fcuny/blog/content/blog/tailscale-docker-https.org new file mode 100644 index 0000000..14e4cf1 --- /dev/null +++ b/users/fcuny/blog/content/blog/tailscale-docker-https.org @@ -0,0 +1,121 @@ +#+TITLE: Tailscale, Docker and HTTPS +#+TAGS[]: docker tailscale traefik +#+DATE: <2021-12-29 Wed> + +I run a number of services in my home network. For the majority of these services, I don't want to make them available on the internet, I want to only be able to access them when I'm on my home network. However, sometimes I'm not at home and I still want to access them. So far I've been using plain [[https://www.wireguard.com/][wireguard]] to achieve this. While the initial configuration for wireguard is pretty simple, it starts to be a bit more cumbersome as I add more hosts/containers. It's also not easy to share keys with other folks if I want to give access to some of the machines or services. For that reason I decided to give a look at [[https://tailscale.com/][tailscale]]. + +There's already a lot of articles about tailscale and how to use and configure it. Their [[https://tailscale.com/kb/][documentation]] is also pretty good, so I won't cover the initial setup. + +As stated above, I want to access some of my services that are running as docker containers from anywhere. For web services, I want to use them through HTTPS, with a valid certificate, and without having to remember on which port the service it's listening. I also don't want to setup a PKI in my home lab for that (and I'm also not interested in configuring split DNS), and instead I prefer to use [[https://letsencrypt.org/][let's encrypt]] with a proper subdomain that is unique for each service. + +The [[https://tailscale.com/kb/1054/dns/][tailscale documentation]] has two suggestions for this: +- use their magicDNS feature / split DNS +- setup a subdomain on a public domain + +Since I already have a public domain that I use for my home network, I decided to go with the second option (I'm also uncertain how to achieve my goal using magicDNS without running tailscale inside the container). + +The public domain I'm using is managed through [[https://cloud.google.com/dns/docs/tutorials/create-domain-tutorial][Google Cloud Domain]]. I create a new record for the services I want to run (for example, ~dash~ for my instance of grafana), using the IP address from the tailscale node the service runs on (e.g. 100.83.51.12). + +For routing the traffic I use [[https://traefik.io/][traefik]]. The configuration for traefik looks like this: +#+begin_src yaml +global: + sendAnonymousUsage: false +providers: + docker: + exposedByDefault: false +entryPoints: + http: + address: ":80" + https: + address: ":443" +certificatesResolvers: + dash: + acme: + email: franck@fcuny.net + storage: acme.json + dnsChallenge: + provider: gcloud +#+end_src + +The important bit here is the ~certificatesResolvers~ part. I'll be using the [[https://doc.traefik.io/traefik/user-guides/docker-compose/acme-dns/][dnsChallenge]] instead of the [[https://doc.traefik.io/traefik/user-guides/docker-compose/acme-http/][httpChallenge]] to obtain the certificate from let's encrypt. For this to work, I need to specify the ~provider~ to be [[https://go-acme.github.io/lego/dns/gcloud/][gcloud]]. I'll also need a service account (see [[https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application][this doc]] to create it). I run ~traefik~ in a docker container, and the ~systemd~ unit file is below. The required bits for using the ~dnsChallenge~ with ~gcloud~ are: +- the environment variable ~GCP_SERVICE_ACCOUNT_FILE~: it contains the credentials so that ~traefik~ can update the DNS record for the challenge +- the environment variable ~GCP_PROJECT~: the name of the GCP project +- mounting the service account file inside the container (I store it on the host under ~/data/containers/traefik/config/sa.json~) + +#+begin_src systemd +[Unit] +Description=traefik proxy +Documentation=https://doc.traefik.io/traefik/ +After=docker.service +Requires=docker.service + +[Service] +Restart=on-failure +ExecStartPre=-/usr/bin/docker kill traefik +ExecStartPre=-/usr/bin/docker rm traefik +ExecStartPre=/usr/bin/docker pull traefik:latest + +ExecStart=/usr/bin/docker run \ + -p 80:80 \ + -p 9080:8080 \ + -p 443:443 \ + --name=traefik \ + -e GCE_SERVICE_ACCOUNT_FILE=/var/run/gcp-service-account.json \ + -e GCE_PROJECT= gcp-super-project \ + --volume=/data/containers/traefik/config/acme.json:/acme.json \ + --volume=/data/containers/traefik/config/traefik.yml:/etc/traefik/traefik.yml:ro \ + --volume=/data/containers/traefik/config/sa.json:/var/run/gcp-service-account.json \ + --volume=/var/run/docker.sock:/var/run/docker.sock:ro \ + traefik:latest +ExecStop=/usr/bin/docker stop traefik + +[Install] +WantedBy=multi-user.target +#+end_src + +As an example, I run [[https://grafana.com/][grafana]] on my home network to view metrics from the various containers / hosts. Let's pretend I use ~example.net~ as my domain. I want to be able to access ~grafana~ via https://dash.example.net. Here's the ~systemd~ unit configuration I use for this: + +#+begin_src systemd +[Unit] +Description=Grafana in a docker container +Documentation=https://grafana.com/docs/ +After=docker.service +Requires=docker.service + +[Service] +Restart=on-failure +RuntimeDirectory=grafana +ExecStartPre=-/usr/bin/docker kill grafana-server +ExecStartPre=-/usr/bin/docker rm grafana-server +ExecStartPre=-/usr/bin/docker pull grafana/grafana:latest + +ExecStart=/usr/bin/docker run \ + -p 3000:3000 \ + -e TZ='America/Los_Angeles' \ + --name grafana-server \ + -v /data/containers/grafana/etc/grafana:/etc/grafana \ + -v /data/containers/grafana/var/lib/grafana:/var/lib/grafana \ + -v /data/containers/grafana/var/log/grafana:/var/log/grafana \ + --user=grafana \ + --label traefik.enable=true \ + --label traefik.http.middlewares.grafana-https-redirect.redirectscheme.scheme=https \ + --label traefik.http.middlewares.grafana-https-redirect.redirectscheme.permanent=true \ + --label traefik.http.routers.grafana-http.rule=Host(`dash.example.net`) \ + --label traefik.http.routers.grafana-http.entrypoints=http \ + --label traefik.http.routers.grafana-http.service=grafana-svc \ + --label traefik.http.routers.grafana-http.middlewares=grafana-https-redirect \ + --label traefik.http.routers.grafana-https.rule=Host(`dash.example.net`) \ + --label traefik.http.routers.grafana-https.entrypoints=https \ + --label traefik.http.routers.grafana-https.tls=true \ + --label traefik.http.routers.grafana-https.tls.certresolver=dash \ + --label traefik.http.routers.grafana-https.service=grafana-svc \ + --label traefik.http.services.grafana-svc.loadbalancer.server.port=3000 \ + grafana/grafana:latest + +ExecStop=/usr/bin/docker stop unifi-controller + +[Install] +WantedBy=multi-user.target +#+end_src + +Now I can access my grafana instance via HTTPS (and http://dash.example.net would redirect to HTTPS) while my tailscale interface is up on the machine I'm using (e.g. my desktop or my phone). -- cgit 1.4.1 From 60de70860976af720e1ce8edd882a6bf0347c0dc Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Wed, 29 Dec 2021 09:37:38 -0800 Subject: css: highlight links with a background color --- users/fcuny/blog/static/css/custom.css | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index cbeac27..2e96fdc 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -21,8 +21,19 @@ hr{ height:2px } -a {color: #494d7e;} -a:visited {color: #494d7e;} +a { + color: #023; + background-color: #eee; +} +a:visited { + color: #345; + background: #eee; +} +a:hover { + color: #000; + text-decoration: none; + background:#ccf; +} span.published, span.updated { display: center; -- cgit 1.4.1 From 550f204f314311f0925c86dbfcc69fa4ec591163 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Wed, 29 Dec 2021 14:18:58 -0800 Subject: css: adjust line height --- users/fcuny/blog/static/css/custom.css | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index 2e96fdc..df75430 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -1,6 +1,5 @@ body { font-family: sans-serif; - line-height:1.6; font-size:18px; color: #000111; background-color: #fbf1c7; @@ -9,7 +8,6 @@ body { padding:0 0.55em; } -h1, h2, h3, h4, h5 {line-height:1.2} h1{margin-top:1em;margin-bottom:0.34em} h2{margin-top:1.25em;margin-bottom:0.41em} h3{margin-top:1.5em;margin-bottom:0.5em} @@ -47,7 +45,6 @@ code { code.verbatim { background-color: #fffff8; } - :not(pre) code{ padding-left:0.1em; padding-right:0.1em; @@ -61,7 +58,6 @@ pre { font-family: monospace; padding: 0.3rem 0.3rem; margin: 0; - line-height: 1.1; overflow-x: auto; border: 1px solid #000; } @@ -87,6 +83,7 @@ table { width: 100%; border-spacing: 0px; outline: none; + line-height: 0.9em; } th, td{ -- cgit 1.4.1 From 024ae916695392a452306b846f4e9a20d5dced9f Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Wed, 29 Dec 2021 14:19:11 -0800 Subject: css: change colors for some sections --- users/fcuny/blog/static/css/custom.css | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index df75430..a38593d 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -92,17 +92,23 @@ th, td{ padding-top:0.4em; padding-bottom:0.4em; } - +thead { + background-color: #ebdbb2; +} table, th, td { border:1px solid black; } blockquote { - background-color: #fffff8; - border-radius: 5px; + background-color: #f2e5bc; font-style: italic; - border-left: 6px solid black; - margin-left: 10.875px; + border-left: 6px solid #7c6f64; + margin-left: 0px; + margin-right: 0px; + padding-left: 0.7em; + padding-right:0.7em; + padding-top:0.2em; + padding-bottom:0.2em; } nav.menu { @@ -119,7 +125,7 @@ nav.menu { .toc { border: 1px solid black; - padding: 1rem; - margin-top: 1rem; + padding: 1em; + margin-top: 1em; color: black; } -- cgit 1.4.1 From 8fd137f98ae94436f99284910f035db7281140a8 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Wed, 29 Dec 2021 14:19:24 -0800 Subject: blog: notes about AMD and Intel CPUs --- .../content/notes/making-sense-intel-amd-cpus.org | 120 +++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 users/fcuny/blog/content/notes/making-sense-intel-amd-cpus.org (limited to 'users/fcuny') diff --git a/users/fcuny/blog/content/notes/making-sense-intel-amd-cpus.org b/users/fcuny/blog/content/notes/making-sense-intel-amd-cpus.org new file mode 100644 index 0000000..4b5541f --- /dev/null +++ b/users/fcuny/blog/content/notes/making-sense-intel-amd-cpus.org @@ -0,0 +1,120 @@ +#+TITLE: Making sense of Intel and AMD CPUs naming +#+DATE: <2021-12-29 Wed> +#+TAGS[]: amd intel cpu +#+toc: t + +* Intel +** Core +The line up for the core family is i3, i5, i7 and i9. As of December 2021, the current generation is Alder Lake (12th generation). + +The brand modifiers are: +- *i3*: laptops/low-end desktop +- *i5*: mainstream users +- *i7*: high-end users +- *i9*: enthusiast users + +How to read a SKU ? Let's use the [[https://ark.intel.com/content/www/us/en/ark/products/134594/intel-core-i712700k-processor-25m-cache-up-to-5-00-ghz.html][i7-12700K]] processor: +- *i7*: high end users +- *12*: 12th generation +- *700*: SKU digits, usually assigned in the order the processors are developed +- *K*: unlocked + +List of suffixes: +| suffix | meaning | +|--------+----------------------------------------| +| G.. | integrated graphics | +| E | embedded | +| F | require discrete graphic card | +| H | high performance for mobile | +| HK | high performance for mobile / unlocked | +| K | unlocked | +| S | special edition | +| T | power optimized lifestyle | +| U | mobile power efficient | +| Y | mobile low power | +| X/XE | unlocked, high end | + +#+begin_quote +*Unlocked,* what does that means ? +A processor with the *K* suffix is made with the an unlocked clock multiplier. When used with some specific chipset, it's possible to overclock the processor. +#+end_quote +*** Sockets/Chipsets +For the Alder Lake generation, the supported socket is the [[https://en.wikipedia.org/wiki/LGA_1700][LGA_1700]]. + +For now the only supported chipset for Alder Lake is the [[https://ark.intel.com/content/www/us/en/ark/products/218833/intel-z690-chipset.html][z690]]. +*** Alder Lake (12th generation) +| model | p-cores | e-cores | GHz (base) | GHz (boosted) | PCIe lanes | memory support | TDP | +|------------+---------+---------+---------------+---------------+--------------------------+----------------+------| +| i9-12900K | 8 (16) | 8 | 3.2/2.4 | 5.1/3.9 | 16 PCIe 5.0 + 4 PCIe 4.0 | DDR5-4800 | 241W | +| i9-12900KF | 8 (16) | 8 | 3.2/2.4 | 5.1/3.9 | - | - | 241W | +| i7-12700K | 8 (16) | 4 | 3.6/2.7 | 4.9/3.8 | - | - | 190W | +| i7-12700KF | 8 (16) | 4 | 3.6/2.7 | 4.9/3.8 | - | - | 190W | +| i5-12600K | 6 (12) | 4 | 3.7/2.8 | 4.9/3.6 | - | - | 150W | +| i5-12600KF | 6 (12) | 4 | 3.7/2.8 | 4.9/3.6 | - | - | 150W | + +- support DDR4 and DDR5 +- support PCIe 4.0 and 5.0 + +Alder lake is an hybrid architecture, featuring both P-cores (performance cores) and E-cores (efficient cores). P-cores are based on the [[https://en.wikipedia.org/wiki/Golden_Cove][Golden Cove]] architecture, while the E-cores are based on the [[https://en.wikipedia.org/wiki/Gracemont_(microarchitecture)][Gracemont]] architecture. + +This is a [[https://www.anandtech.com/show/16881/a-deep-dive-into-intels-alder-lake-microarchitectures/2][good article]] to read about this model. Inside the processor there's a microcontroller that monitors what each thread is doing. This can be used by the OS scheduler to hint on which core a thread should be scheduled on (between performance or efficiency). + +As of December 2021 this is not yet properly supported by the Linux kernel. +** Xeon +Xeon is the brand of Intel processor designed for non-consumer servers and workstations. +The most recent generations are: +- Skylake (2017) +- Cascade lake (2019) +- Cooper lake (2020) + +The following brand identifiers are used: +- platinium +- gold +- silver +- bronze +* AMD +** Ryzen +There are multiple generation for this brand of processors. They are based on the [[https://en.wikipedia.org/wiki/Zen_(microarchitecture)][zen micro architecture]]. The current (as of December 2021) generation is Ryzen 5000. + +The brand modifiers are: +- ryzen 3: entry level +- ryzen 5: mainstream +- ryzen 9: high end performance +- ryzen 9:enthusiast + +List of suffixes: +| suffix | meaning | +|--------+--------------------------------------------| +| X | high performance | +| G | integrated graphics | +| T | power optimized lifecycle | +| S | low power desktop with integrated graphics | +| H | high performance mobile | +| U | standard mobile | +| M | low power mobile | + +** EPYC +EPYC is the AMD brand of processors for the server market, based on the zen architecture. They use the [[https://en.wikipedia.org/wiki/Socket_SP3][SP3]] socket. The EPYC processor is chipset free. +** Threadripper +The threadripper is for high performance desktop. It uses the [[https://en.wikipedia.org/wiki/Socket_TR4][TR4]] socket. At the moment there's only one chipset that supports this process, the [[https://en.wikipedia.org/wiki/List_of_AMD_chipsets#TR4_chipsets][X399]]. + +The threadripper based on zen3 architecture is not yet released, but it's expected to hit the market in the first half of Q1 2022. +** Sockets/Chipsets +The majority of these processors use the [[https://en.wikipedia.org/wiki/Socket_AM4][AM4 socket]]. The threadripper line uses different sockets. + +There are multiple [[https://en.wikipedia.org/wiki/Socket_AM4#Chipsets][chipset]] for the AM4 socket. The more advanced ones are the B550 and the X570. + +The threadripper processors use the TR4, sTRX4 and sWRX8 sockets. +** Zen 3 +Zen 3 was released in November 2020. +| model | cores | GHz (base) | GHz (boosted) | PCIe lanes | memory support | TDP | +|---------------+---------+------------+---------------+------------+----------------+------| +| ryzen 5 5600x | 6 (12) | 3.7 | 4.6 | 24 | DDR4-3200 | 65W | +| ryzen 7 5800 | 8 (16) | 3.4 | 4.6 | 24 | DDR4-3200 | 65W | +| ryzen 7 5800x | 8 (16) | 3.8 | 4.7 | 24 | DDR4-3200 | 105W | +| ryzen 9 5900 | 12 (24) | 3.0 | 4.7 | 24 | DDR4-3200 | 65W | +| ryzen 9 5900x | 12 (24) | 3.7 | 4.8 | 24 | DDR4-3200 | 105W | +| ryzen 9 5950x | 16 (32) | 3.4 | 4.9 | 24 | DDR4-3200 | 105W | + +- support PCIe 3.0 and PCIe 4.0 (except for the G series) +- only support DDR4 -- cgit 1.4.1 From 949829af5c95c19b3e48e47996bfea3252237338 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sat, 8 Jan 2022 10:07:36 -0800 Subject: blog: add content about PCIe --- .../fcuny/blog/content/notes/stuff-about-pcie.org | 196 +++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 users/fcuny/blog/content/notes/stuff-about-pcie.org (limited to 'users/fcuny') diff --git a/users/fcuny/blog/content/notes/stuff-about-pcie.org b/users/fcuny/blog/content/notes/stuff-about-pcie.org new file mode 100644 index 0000000..4d1a825 --- /dev/null +++ b/users/fcuny/blog/content/notes/stuff-about-pcie.org @@ -0,0 +1,196 @@ +#+TITLE: Stuff about PCIe +#+DATE: <2022-01-03 Mon> +#+TAGS[]: linux hardware +#+toc: t + +* Speed +The most common versions are 3 and 4, while 5 is starting to be available with newer Intel processors. + +| ver | encoding | transfer rate | x1 | x2 | x4 | x8 | x16 | +|-----+-----------+---------------+------------+-------------+------------+------------+-------------| +| 1 | 8b/10b | 2.5GT/s | 250MB/s | 500MB/s | 1GB/s | 2GB/s | 4GB/s | +| 2 | 8b/10b | 5.0GT/s | 500MB/s | 1GB/s | 2GB/s | 4GB/s | 8GB/s | +| 3 | 128b/130b | 8.0GT/s | 984.6 MB/s | 1.969 GB/s | 3.94 GB/s | 7.88 GB/s | 15.75 GB/s | +| 4 | 128b/130b | 16.0GT/s | 1969 MB/s | 3.938 GB/s | 7.88 GB/s | 15.75 GB/s | 31.51 GB/s | +| 5 | 128b/130b | 32.0GT/s | 3938 MB/s | 7.877 GB/s | 15.75 GB/s | 31.51 GB/s | 63.02 GB/s | +| 6 | 128b/130 | 64.0 GT/s | 7877 MB/s | 15.754 GB/s | 31.51 GB/s | 63.02 GB/s | 126.03 GB/s | + +This is a [[https://community.mellanox.com/s/article/understanding-pcie-configuration-for-maximum-performance][useful]] link to understand the formula: Maximum PCIe Bandwidth = *SPEED* * *WIDTH* * (1 - ENCODING) - 1Gb/s. + +We remove 1Gb/s for protocol overhead and error corrections. The main difference between the generations besides the supported speed is the encoding overhead of the packet. For generations 1 and 2, each packet sent on the PCIe has 20% PCIe headers overhead. This was improved in generation 3, where the overhead was reduced to 1.5% (2/130) - see [[https://en.wikipedia.org/wiki/8b/10b_encoding][8b/10b encoding]] and [[https://en.wikipedia.org/wiki/64b/66b_encoding][128b/130b encoding]]. + +If we apply the formula, for a PCIe version 3 device we can expect 3.7GB/s of data transfer rate: +#+begin_src +8GT/s * 4 lanes * (1 - 2/130) - 1G = 32G * 0.985 - 1G = ~30Gb/s -> 3750MB/s +#+end_src +* Topology +The easiest way to see the PCIe topology is with =lspci=: +#+begin_src +$ lspci -tv +-[0000:00]-+-00.0 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Root Complex + +-01.0 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge + +-01.1-[01]----00.0 OCZ Technology Group, Inc. RD400/400A SSD + +-01.3-[02-03]----00.0-[03]----00.0 ASPEED Technology, Inc. ASPEED Graphics Family + +-01.5-[04]--+-00.0 Intel Corporation I350 Gigabit Network Connection + | +-00.1 Intel Corporation I350 Gigabit Network Connection + | +-00.2 Intel Corporation I350 Gigabit Network Connection + | \-00.3 Intel Corporation I350 Gigabit Network Connection + +-02.0 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge + +-03.0 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge + +-04.0 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge + +-07.0 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge + +-07.1-[05]--+-00.0 Advanced Micro Devices, Inc. [AMD] Zeppelin/Raven/Raven2 PCIe Dummy Function + | +-00.2 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Platform Security Processor + | \-00.3 Advanced Micro Devices, Inc. [AMD] Zeppelin USB 3.0 Host controller + +-08.0 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge + +-08.1-[06]--+-00.0 Advanced Micro Devices, Inc. [AMD] Zeppelin/Renoir PCIe Dummy Function + | +-00.1 Advanced Micro Devices, Inc. [AMD] Zeppelin Cryptographic Coprocessor NTBCCP + | +-00.2 Advanced Micro Devices, Inc. [AMD] FCH SATA Controller [AHCI mode] + | \-00.3 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) HD Audio Controller + +-14.0 Advanced Micro Devices, Inc. [AMD] FCH SMBus Controller + +-14.3 Advanced Micro Devices, Inc. [AMD] FCH LPC Bridge + +-18.0 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 0 + +-18.1 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 1 + +-18.2 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 2 + +-18.3 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 3 + +-18.4 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 4 + +-18.5 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 5 + +-18.6 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 6 + \-18.7 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 7 +#+end_src +* View a single device +#+begin_src +$ lspci -s 0000:01:00.0 +01:00.0 Non-Volatile memory controller: OCZ Technology Group, Inc. RD400/400A SSD (rev 01) +#+end_src +* Reading =lspci= output +#+begin_src +$ sudo lspci -vvv -s 0000:01:00.0 +01:00.0 Non-Volatile memory controller: OCZ Technology Group, Inc. RD400/400A SSD (rev 01) (prog-if 02 [NVM Express]) + Subsystem: OCZ Technology Group, Inc. RD400/400A SSD + Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ + Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- SERR- Date: Sat, 8 Jan 2022 10:07:43 -0800 Subject: index: update current job --- users/fcuny/blog/layouts/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/index.html b/users/fcuny/blog/layouts/index.html index 9e15e77..586aaa5 100644 --- a/users/fcuny/blog/layouts/index.html +++ b/users/fcuny/blog/layouts/index.html @@ -2,7 +2,7 @@

        {{ .Site.Home.Title }}

        -

        I'm currently working as an Engineer at Twitter, on the Compute team.

        +

        I'm an engineer currently working as a break. Previously I was a Site Reliability Engineer at Twitter, on the Compute team.

        Contact

          -- cgit 1.4.1 From c73246820fcb27009a8e521a4039241bad280a77 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Mon, 10 Jan 2022 11:46:19 -0800 Subject: index: rephrase --- users/fcuny/blog/layouts/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/index.html b/users/fcuny/blog/layouts/index.html index 586aaa5..21a86b8 100644 --- a/users/fcuny/blog/layouts/index.html +++ b/users/fcuny/blog/layouts/index.html @@ -2,7 +2,7 @@

          {{ .Site.Home.Title }}

          -

          I'm an engineer currently working as a break. Previously I was a Site Reliability Engineer at Twitter, on the Compute team.

          +

          I'm an engineer currently on a break. Previously I was a Site Reliability Engineer working on Twitter's compute platform.

          Contact

            -- cgit 1.4.1 From 0c79b62d7363b6497fd8d7d667869f527b2f8494 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Thu, 13 Jan 2022 14:02:25 -0800 Subject: css: more tweaking --- users/fcuny/blog/static/css/custom.css | 50 ++++++++++++++-------------------- 1 file changed, 21 insertions(+), 29 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index a38593d..39d3d8c 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -19,18 +19,15 @@ hr{ height:2px } -a { - color: #023; - background-color: #eee; -} -a:visited { - color: #345; - background: #eee; -} a:hover { - color: #000; text-decoration: none; - background:#ccf; + border-bottom: 1px solid; +} + +a { + text-decoration: none; + border-bottom: 1px dotted; + color: black; } span.published, span.updated { @@ -41,25 +38,25 @@ span.published, span.updated { code { font-family: monospace; font-size: 80%; -} -code.verbatim { - background-color: #fffff8; -} -:not(pre) code{ padding-left:0.1em; padding-right:0.1em; - border-radius:2px; + border-radius:4px; + background-color: #f7f7f7; } -.highlight pre {background-color: #fffff8 !important} -.highlight {border-radius: 5px} +ol { + line-height: 0.8em; +} pre { font-family: monospace; + font-size: 90%; padding: 0.3rem 0.3rem; margin: 0; overflow-x: auto; border: 1px solid #000; + border-radius: 4px; + background-color: #f7f7f7; } .meta_tags { @@ -70,8 +67,9 @@ pre { background-color: #eee; } -.meta_tags a:link, .meta_tags a:visited { +.meta_tags a { text-decoration: none; + border-bottom: none; } .meta_date { @@ -83,7 +81,6 @@ table { width: 100%; border-spacing: 0px; outline: none; - line-height: 0.9em; } th, td{ @@ -100,15 +97,10 @@ table, th, td { } blockquote { - background-color: #f2e5bc; - font-style: italic; - border-left: 6px solid #7c6f64; - margin-left: 0px; - margin-right: 0px; - padding-left: 0.7em; - padding-right:0.7em; - padding-top:0.2em; - padding-bottom:0.2em; + page-break-inside:avoid; + padding:10px 20px; + margin:0 0 20px; + border-left:5px solid #eee } nav.menu { -- cgit 1.4.1 From 4f3785b826d5359b64c916b0bbb6f77490ec3672 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sat, 15 Jan 2022 12:39:41 -0800 Subject: blog: leaving twitter --- users/fcuny/blog/content/blog/leaving-twitter.org | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 users/fcuny/blog/content/blog/leaving-twitter.org (limited to 'users/fcuny') diff --git a/users/fcuny/blog/content/blog/leaving-twitter.org b/users/fcuny/blog/content/blog/leaving-twitter.org new file mode 100644 index 0000000..9bc5027 --- /dev/null +++ b/users/fcuny/blog/content/blog/leaving-twitter.org @@ -0,0 +1,10 @@ +#+TITLE: Leaving Twitter +#+DATE: <2022-01-15 Sat> + +January 7th 2022 was my last day at Twitter, after more than 7 years at the company. + +The first few years I worked as an SRE in the core-storage team, with the PUB/SUB and key-value store teams. + +I spend the last four years working with the Compute team, both maintaining and operating our (very large) Aurora/Mesos clusters, and also working on the adoption of kubernetes, both for our data centers and for the cloud. Working with Compute was extremely fulfilling to me, as I worked closely with our hardware engineering and kernel/operating system teams. + +During these 7 years, I was constantly pushed by my coworkers to grow, to step up to new challenges, and I learned a tremendous amount about running large scale distributed systems. I'm extremely glad for that experience, it was by far the most interesting and challenging job I've ever had so far. -- cgit 1.4.1 From 1dc0a3a89c5493bbd4b454413d22f8c774eec470 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Fri, 21 Jan 2022 11:13:35 -0800 Subject: nav: drop one item from the menu --- users/fcuny/blog/config.toml | 7 ------- 1 file changed, 7 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/config.toml b/users/fcuny/blog/config.toml index 7162180..1fe49bc 100644 --- a/users/fcuny/blog/config.toml +++ b/users/fcuny/blog/config.toml @@ -20,13 +20,6 @@ enableGitInfo = true tags = "/tags/:slug/" [menu] - [[menu.main]] - identifier = "home" - name = "home" - title = "fcuny.net" - url = "/" - weight = 100 - [[menu.main]] identifier = "articles" name = "blog" -- cgit 1.4.1 From 528159360435f82fc5f4806a2bac1a53044cb070 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Fri, 21 Jan 2022 11:13:56 -0800 Subject: post: change formatting for the date --- users/fcuny/blog/layouts/_default/single.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/_default/single.html b/users/fcuny/blog/layouts/_default/single.html index 165c568..4f21ded 100644 --- a/users/fcuny/blog/layouts/_default/single.html +++ b/users/fcuny/blog/layouts/_default/single.html @@ -5,17 +5,17 @@

            {{ .Title }}

            - {{- $pub := .Date.Format "2006-01-02" -}} + {{- $pub := .Date.Format "Jan 2, 2006" -}} {{- $mod := "" -}} {{- if (not .GitInfo) }} - {{- $mod = .Lastmod.Format "2006-01-02" -}} + {{- $mod = .Lastmod.Format "Jan 2, 2006" -}} {{ else }} - {{- $mod = .Page.GitInfo.CommitDate.Format "2006-01-02" -}} + {{- $mod = .Page.GitInfo.CommitDate.Format "Jan 2, 2006" -}} {{ end -}} {{ if eq $pub $mod }}
            published {{ $pub }}
            {{ else }} -
            published {{ $pub }}, last modified {{ $mod }}
            +
            published {{ $pub }} - last modified {{ $mod }}
            {{ end }} {{ if .Params.tags }}
            -- cgit 1.4.1 From cd425907331d0265393719ee9191d9cccb1a4edb Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Fri, 21 Jan 2022 11:14:06 -0800 Subject: nav: align the menu items to the right --- users/fcuny/blog/layouts/partials/header.html | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/partials/header.html b/users/fcuny/blog/layouts/partials/header.html index 9118a50..e579329 100644 --- a/users/fcuny/blog/layouts/partials/header.html +++ b/users/fcuny/blog/layouts/partials/header.html @@ -1,7 +1,12 @@
            -
            -- cgit 1.4.1 From 96f3f6484a92a63f363bbb710d5e0ad23fce4f37 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Fri, 21 Jan 2022 11:14:25 -0800 Subject: css: major cleanup --- users/fcuny/blog/static/css/custom.css | 160 +++++++++++++++++---------------- 1 file changed, 84 insertions(+), 76 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index 39d3d8c..c24db91 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -1,123 +1,131 @@ body { - font-family: sans-serif; - font-size:18px; - color: #000111; - background-color: #fbf1c7; - margin:1em auto; - max-width:750px; - padding:0 0.55em; + font-family: sans-serif; + font-size: 1.125em; + line-height: 1.5; + color: #37474f; + word-wrap: break-word; + margin: 1em auto; + max-width: 750px; + padding: 0 0.55em; } -h1{margin-top:1em;margin-bottom:0.34em} -h2{margin-top:1.25em;margin-bottom:0.41em} -h3{margin-top:1.5em;margin-bottom:0.5em} +h1 { + font-size: 2em; +} + +h1 {margin-top: 1em; margin-bottom: 0.34em} +h2 {margin-top: 1.25em; margin-bottom: 0.41em} +h3 {margin-top: 1.5em; margin-bottom: 0.5em} hr{ - color:#000111; - background-color:#000111; - border:none; - height:2px + color:#000111; + background-color:#000111; + border:none; + height:2px } -a:hover { - text-decoration: none; - border-bottom: 1px solid; -} +a {border-bottom: .125em dashed #bdbdbd} a { - text-decoration: none; - border-bottom: 1px dotted; - color: black; + color:#212121; + text-decoration:none; + transition:color .1s ease-in-out } +a:hover, a:focus, a:active {color:#37474f} + +a:hover, a:focus {border-bottom-color: #a6071b} + span.published, span.updated { - display: center; - font-style: oblique; + display: center; + font-style: oblique; } code { - font-family: monospace; - font-size: 80%; - padding-left:0.1em; - padding-right:0.1em; - border-radius:4px; - background-color: #f7f7f7; + font-family: monospace; + padding-left:0.1em; + padding-right:0.1em; + border-radius:4px; + background-color: #fafafa; } -ol { - line-height: 0.8em; -} +p code {color: #f8546a} pre { - font-family: monospace; - font-size: 90%; - padding: 0.3rem 0.3rem; - margin: 0; - overflow-x: auto; - border: 1px solid #000; - border-radius: 4px; - background-color: #f7f7f7; + font-family: monospace; + margin: 0; + word-wrap: normal; + padding:1.125em; + overflow-x: auto; + border: 1px solid #ccc; + border-radius: 3px; + background-color: #fafafa; } .meta_tags { - border-radius: 8px; - padding: 0 .5rem; - font-size: 80%; - border: 2px solid #eee; - background-color: #eee; + border-radius: 8px; + padding: 0 .5rem; + font-size: 80%; + border: 2px solid #eee; + background-color: #eee; } .meta_tags a { - text-decoration: none; - border-bottom: none; + text-decoration: none; + border-bottom: none; } .meta_date { - font-style: italic; - font-size: 80%; + font-style: italic; + font-size: 80%; } table { - width: 100%; - border-spacing: 0px; - outline: none; + width: 100%; + border-spacing: 0px; + outline: none; } th, td{ - padding-left:0.7em; - padding-right:0.7em; - padding-top:0.4em; - padding-bottom:0.4em; + padding-left: 0.7em; + padding-right: 0.7em; + padding-top: 0.4em; + padding-bottom: 0.4em; } thead { - background-color: #ebdbb2; -} -table, th, td { - border:1px solid black; + background-color: #ebdbb2; } +table, th, td {border: 1px solid black} blockquote { - page-break-inside:avoid; - padding:10px 20px; - margin:0 0 20px; - border-left:5px solid #eee + font-size: 1.125em; + font-style: italic; + margin: 0 0 1.5em; + padding-left: 1em; + border-left: .2em solid #bdbdbd +} + +nav { + width: 100%; + padding-right: 10px; + display: flex; + justify-content: space-between; + align-items: center; } -nav.menu { - display: flex; - justify-content: flex-start; - flex-direction: row; - flex-wrap: nowrap; - margin: 0 auto; +.nav-links { + list-style: none; + display: flex; } -.menu-item { - padding-right: 8px; +.navbar a { + display: inline-block; + padding-right: 10px; } .toc { - border: 1px solid black; - padding: 1em; - margin-top: 1em; - color: black; + border: 1px solid black; + padding: 1em; + margin-top: 1em; + color: black; } -- cgit 1.4.1 From ce37a0c5b81118cd9b611417bf28e72b348bb7e1 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Fri, 21 Jan 2022 11:18:27 -0800 Subject: nav: use 'fcuny.net' instead of template variable Otherwise it's the name of the site, which is not what I'm looking for here. --- users/fcuny/blog/layouts/partials/header.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/partials/header.html b/users/fcuny/blog/layouts/partials/header.html index e579329..dede0ae 100644 --- a/users/fcuny/blog/layouts/partials/header.html +++ b/users/fcuny/blog/layouts/partials/header.html @@ -1,7 +1,7 @@
    + {{ end }} -- cgit 1.4.1 From abd51f109bfa17642d306deed1a0b0c229b0af18 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 23 Jan 2022 18:22:47 -0800 Subject: layout: proper TOC There's a need for two TOCs in the layout: one for when the page is on mobile; one for non mobile. When we are on mobile, we display the first TOC, before the article. When we're not on mobile, we hide that TOC and display one after the document. We restructure a bit the layout so that's it's a bit more readable too, and close tags properly. --- users/fcuny/blog/layouts/_default/single.html | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/_default/single.html b/users/fcuny/blog/layouts/_default/single.html index 4f21ded..524145a 100644 --- a/users/fcuny/blog/layouts/_default/single.html +++ b/users/fcuny/blog/layouts/_default/single.html @@ -1,6 +1,6 @@ {{ define "main" }} -
    +

    {{ .Title }}

    @@ -32,14 +32,23 @@
    {{ if .Params.toc }} -
    - Table of Contents +
    + Table of contents {{ .TableOfContents }}
    {{ end }} +
    {{ .Content }} +
    + +
    -
    +{{ if .Params.toc }} +
    + Table of contents + {{ .TableOfContents }} +
    +{{ end }} {{ end }} -- cgit 1.4.1 From 549eb4cb67215b2c2146ad61c7a56583299f092b Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 23 Jan 2022 18:48:19 -0800 Subject: css: TOC location based on display's size Depending on the size of the display, display the TOC either before the article or on the right of the article and let's make it sticky. --- users/fcuny/blog/static/css/custom.css | 101 ++++++++++++++++++++++++++------- 1 file changed, 82 insertions(+), 19 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index bbf93a7..80b07a0 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -3,17 +3,27 @@ body { font-size: 1.125em; line-height: 1.5; color: #37474f; - word-wrap: break-word; margin: 1em auto; - max-width: 750px; padding: 0 0.55em; + max-width: 45rem; +} + +@media screen and (min-width:58rem) { + body, + main { + max-width:calc(45rem + 15rem); + } + main { + display: flex; + } } h1 { font-size: 2em; + margin-top: 1em; + margin-bottom: 0.34em; } -h1 {margin-top: 1em; margin-bottom: 0.34em} h2 {margin-top: 1.25em; margin-bottom: 0.41em} h3 {margin-top: 1.5em; margin-bottom: 0.5em} @@ -24,17 +34,19 @@ hr{ height:2px } -a {border-bottom: .125em dashed #bdbdbd} - a { color:#047bc2; - text-decoration:none; - transition:color .1s ease-in-out + transition:color .1s ease-in-out; } -a:hover, a:focus, a:active {color:#047bc2} - -a:hover, a:focus {border-bottom-color: #047bc2} +a:link, +a:hover, +a:focus, +a:active { + color:#047bc2; + text-decoration: underline; + text-underline-offset:.2rem +} span.published, span.updated { display: center; @@ -43,9 +55,9 @@ span.published, span.updated { code { font-family: monospace; - padding-left:0.1em; - padding-right:0.1em; - border-radius:4px; + padding-left: 0.1em; + padding-right: 0.1em; + border-radius: 4px; background-color: #fafafa; } @@ -62,6 +74,10 @@ pre { background-color: #fafafa; } +.meta { + display: row; +} + .meta_tags { border-radius: 8px; padding: 0 .5rem; @@ -73,6 +89,7 @@ pre { .meta_tags a { text-decoration: none; border-bottom: none; + color: #005a9c; } .meta_date { @@ -102,7 +119,7 @@ table, th, td { } blockquote { - font-size: 1.125em; + font-size: 1em; font-style: italic; margin: 0 0 1.5em; padding-left: 1em; @@ -115,6 +132,13 @@ nav { display: flex; justify-content: space-between; align-items: center; + padding-top: 0.5rem; +} + +@media screen and (min-width:58rem) { + nav { + max-width: calc(45rem + 15rem); + } } .nav-links { @@ -127,9 +151,48 @@ nav { padding-right: 10px; } -.toc { - border: 1px solid black; - padding: 1em; - margin-top: 1em; - color: black; +article { + max-width: 45rem; +} + +.toc {display: none} + +#toc_small { + font-size: 0.9rem; + margin-bottom: 2rem; + margin-top: 2rem; +} +@media screen and (min-width:58rem) { + #toc_small {display: none;} +} + +summary { + display:flex; + flex-direction:column; +} + +#TableOfContents > ul, #TableOfContents > ul > li > ul { + list-style: none; + margin: 0; + padding: 0; +} + +#TableOfContents li {margin-bottom: 1rem;} + +@media screen and (min-width:58rem) { + .toc { + padding-left: 1rem; + padding-top: 4.5rem; + font-size: 0.8em; + display:block; + position:sticky; + top:0; + align-self:flex-start; + max-width:15rem; + z-index:1; + } + #TableOfContents { + border-left: 3px solid #eee; + padding-left: 1rem; + } } -- cgit 1.4.1 From 25910d969dcdb4f8eb7383d0953dbd8b60d0dedf Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 23 Jan 2022 18:49:53 -0800 Subject: layout: no need for a class to element 'article' --- users/fcuny/blog/layouts/_default/list.html | 2 +- users/fcuny/blog/layouts/_default/single.html | 2 +- users/fcuny/blog/layouts/index.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/_default/list.html b/users/fcuny/blog/layouts/_default/list.html index 6d1c04f..d2c59a7 100644 --- a/users/fcuny/blog/layouts/_default/list.html +++ b/users/fcuny/blog/layouts/_default/list.html @@ -1,6 +1,6 @@ {{ define "main" }} -
    +
    {{ $pgs := where .Data.Pages "Params.hidden" "ne" "true" }} {{ partial "postlist" $pgs }} diff --git a/users/fcuny/blog/layouts/_default/single.html b/users/fcuny/blog/layouts/_default/single.html index 524145a..fe2477e 100644 --- a/users/fcuny/blog/layouts/_default/single.html +++ b/users/fcuny/blog/layouts/_default/single.html @@ -38,7 +38,7 @@
    {{ end }} -
    +
    {{ .Content }}
    diff --git a/users/fcuny/blog/layouts/index.html b/users/fcuny/blog/layouts/index.html index 523ad08..2ab8c40 100644 --- a/users/fcuny/blog/layouts/index.html +++ b/users/fcuny/blog/layouts/index.html @@ -1,6 +1,6 @@ {{ define "main" }} -
    +

    {{ .Site.Home.Title }}

    -- cgit 1.4.1 From e9dd95b6d50c2030a0efe819257ff557f8fbf2a8 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 23 Jan 2022 19:11:39 -0800 Subject: CSS: switch from class to id These elements are unique on each page. --- users/fcuny/blog/layouts/_default/single.html | 10 +++++----- users/fcuny/blog/static/css/custom.css | 18 +++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/layouts/_default/single.html b/users/fcuny/blog/layouts/_default/single.html index fe2477e..7a85a05 100644 --- a/users/fcuny/blog/layouts/_default/single.html +++ b/users/fcuny/blog/layouts/_default/single.html @@ -4,7 +4,7 @@

    {{ .Title }}

    -
    +
    {{- $pub := .Date.Format "Jan 2, 2006" -}} {{- $mod := "" -}} {{- if (not .GitInfo) }} @@ -13,9 +13,9 @@ {{- $mod = .Page.GitInfo.CommitDate.Format "Jan 2, 2006" -}} {{ end -}} {{ if eq $pub $mod }} -
    published {{ $pub }}
    +
    published {{ $pub }}
    {{ else }} -
    published {{ $pub }} - last modified {{ $mod }}
    +
    published {{ $pub }} - last modified {{ $mod }}
    {{ end }} {{ if .Params.tags }}
    @@ -25,7 +25,7 @@ tags: {{ end }} {{ range $idx, $tag := .Params.tags }} - {{ $tag }} + {{ $tag }} {{ end }}
    {{ end }} @@ -45,7 +45,7 @@
    {{ if .Params.toc }} -
    +
    Table of contents {{ .TableOfContents }}
    diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index 80b07a0..3f4a142 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -74,27 +74,27 @@ pre { background-color: #fafafa; } -.meta { +#meta { display: row; } -.meta_tags { +#meta_tags { border-radius: 8px; padding: 0 .5rem; - font-size: 80%; + font-size: 0.9rem; border: 2px solid #eee; background-color: #eee; } -.meta_tags a { +#meta_tags a { text-decoration: none; border-bottom: none; color: #005a9c; } -.meta_date { +#meta_date { font-style: italic; - font-size: 80%; + font-size: 0.9rem; } table { @@ -155,7 +155,7 @@ article { max-width: 45rem; } -.toc {display: none} +#toc {display: none} #toc_small { font-size: 0.9rem; @@ -180,10 +180,10 @@ summary { #TableOfContents li {margin-bottom: 1rem;} @media screen and (min-width:58rem) { - .toc { + #toc { padding-left: 1rem; padding-top: 4.5rem; - font-size: 0.8em; + font-size: 0.9rem; display:block; position:sticky; top:0; -- cgit 1.4.1 From f84fad933c7fb0446b042bf33d1ae5f960e9920d Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 23 Jan 2022 19:22:15 -0800 Subject: CSS: adjust some font sizes --- users/fcuny/blog/static/css/custom.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index 3f4a142..c802354 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -19,7 +19,7 @@ body { } h1 { - font-size: 2em; + font-size: 2rem; margin-top: 1em; margin-bottom: 0.34em; } @@ -119,7 +119,7 @@ table, th, td { } blockquote { - font-size: 1em; + font-size: 0.95rem; font-style: italic; margin: 0 0 1.5em; padding-left: 1em; -- cgit 1.4.1 From 26c15f90a97c21304d3a4494ad28d66d374fff0a Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 23 Jan 2022 19:55:55 -0800 Subject: CSS: improve readability Using Firefox' accessibility tool as a guide. --- users/fcuny/blog/static/css/custom.css | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index c802354..ae6d674 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -55,21 +55,24 @@ span.published, span.updated { code { font-family: monospace; - padding-left: 0.1em; - padding-right: 0.1em; + padding-left: 0.2em; + padding-right: 0.2em; border-radius: 4px; - background-color: #fafafa; } -p code {color: #f8546a} +p code { + color: black; + background-color: #eee; + padding: 0 0.2rem; +} pre { font-family: monospace; margin: 0; word-wrap: normal; - padding:1.125em; + padding: 0.8em; overflow-x: auto; - border: 1px solid #ccc; + border: 1px solid #eee; border-radius: 3px; background-color: #fafafa; } -- cgit 1.4.1 From 179428da59b076b69789a484204488b92f416d59 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 23 Jan 2022 19:56:11 -0800 Subject: notes: remove some columns for the various CPUs --- .../content/notes/making-sense-intel-amd-cpus.org | 42 +++++++++++----------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/content/notes/making-sense-intel-amd-cpus.org b/users/fcuny/blog/content/notes/making-sense-intel-amd-cpus.org index 4b5541f..2394085 100644 --- a/users/fcuny/blog/content/notes/making-sense-intel-amd-cpus.org +++ b/users/fcuny/blog/content/notes/making-sense-intel-amd-cpus.org @@ -43,17 +43,19 @@ For the Alder Lake generation, the supported socket is the [[https://en.wikipedi For now the only supported chipset for Alder Lake is the [[https://ark.intel.com/content/www/us/en/ark/products/218833/intel-z690-chipset.html][z690]]. *** Alder Lake (12th generation) -| model | p-cores | e-cores | GHz (base) | GHz (boosted) | PCIe lanes | memory support | TDP | -|------------+---------+---------+---------------+---------------+--------------------------+----------------+------| -| i9-12900K | 8 (16) | 8 | 3.2/2.4 | 5.1/3.9 | 16 PCIe 5.0 + 4 PCIe 4.0 | DDR5-4800 | 241W | -| i9-12900KF | 8 (16) | 8 | 3.2/2.4 | 5.1/3.9 | - | - | 241W | -| i7-12700K | 8 (16) | 4 | 3.6/2.7 | 4.9/3.8 | - | - | 190W | -| i7-12700KF | 8 (16) | 4 | 3.6/2.7 | 4.9/3.8 | - | - | 190W | -| i5-12600K | 6 (12) | 4 | 3.7/2.8 | 4.9/3.6 | - | - | 150W | -| i5-12600KF | 6 (12) | 4 | 3.7/2.8 | 4.9/3.6 | - | - | 150W | - -- support DDR4 and DDR5 -- support PCIe 4.0 and 5.0 +| model | p-cores | e-cores | GHz (base) | GHz (boosted) | TDP | +|------------+---------+---------+------------+---------------+------| +| i9-12900K | 8 (16) | 8 | 3.2/2.4 | 5.1/3.9 | 241W | +| i9-12900KF | 8 (16) | 8 | 3.2/2.4 | 5.1/3.9 | 241W | +| i7-12700K | 8 (16) | 4 | 3.6/2.7 | 4.9/3.8 | 190W | +| i7-12700KF | 8 (16) | 4 | 3.6/2.7 | 4.9/3.8 | 190W | +| i5-12600K | 6 (12) | 4 | 3.7/2.8 | 4.9/3.6 | 150W | +| i5-12600KF | 6 (12) | 4 | 3.7/2.8 | 4.9/3.6 | 150W | + +- support DDR4 and DDR5 (up to DDR5-4800) +- support PCIe 4.0 and 5.0 (16 PCIe 5.0 and 4 PCIe 4.0) + +The socket used is the [[https://en.wikipedia.org/wiki/LGA_1700][LGA 1700]]. Alder lake is an hybrid architecture, featuring both P-cores (performance cores) and E-cores (efficient cores). P-cores are based on the [[https://en.wikipedia.org/wiki/Golden_Cove][Golden Cove]] architecture, while the E-cores are based on the [[https://en.wikipedia.org/wiki/Gracemont_(microarchitecture)][Gracemont]] architecture. @@ -107,14 +109,14 @@ There are multiple [[https://en.wikipedia.org/wiki/Socket_AM4#Chipsets][chipset] The threadripper processors use the TR4, sTRX4 and sWRX8 sockets. ** Zen 3 Zen 3 was released in November 2020. -| model | cores | GHz (base) | GHz (boosted) | PCIe lanes | memory support | TDP | -|---------------+---------+------------+---------------+------------+----------------+------| -| ryzen 5 5600x | 6 (12) | 3.7 | 4.6 | 24 | DDR4-3200 | 65W | -| ryzen 7 5800 | 8 (16) | 3.4 | 4.6 | 24 | DDR4-3200 | 65W | -| ryzen 7 5800x | 8 (16) | 3.8 | 4.7 | 24 | DDR4-3200 | 105W | -| ryzen 9 5900 | 12 (24) | 3.0 | 4.7 | 24 | DDR4-3200 | 65W | -| ryzen 9 5900x | 12 (24) | 3.7 | 4.8 | 24 | DDR4-3200 | 105W | -| ryzen 9 5950x | 16 (32) | 3.4 | 4.9 | 24 | DDR4-3200 | 105W | +| model | cores | GHz (base) | GHz (boosted) | PCIe lanes | TDP | +|---------------+---------+------------+---------------+------------+------| +| ryzen 5 5600x | 6 (12) | 3.7 | 4.6 | 24 | 65W | +| ryzen 7 5800 | 8 (16) | 3.4 | 4.6 | 24 | 65W | +| ryzen 7 5800x | 8 (16) | 3.8 | 4.7 | 24 | 105W | +| ryzen 9 5900 | 12 (24) | 3.0 | 4.7 | 24 | 65W | +| ryzen 9 5900x | 12 (24) | 3.7 | 4.8 | 24 | 105W | +| ryzen 9 5950x | 16 (32) | 3.4 | 4.9 | 24 | 105W | - support PCIe 3.0 and PCIe 4.0 (except for the G series) -- only support DDR4 +- only support DDR4 (up to DDR4-3200) -- cgit 1.4.1 From a5098a67a7d18eb9c17babd5421886da04a63158 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 23 Jan 2022 19:56:42 -0800 Subject: build: use more recent version of hugo --- users/fcuny/blog/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/Dockerfile b/users/fcuny/blog/Dockerfile index 5e2b55a..64c0f97 100644 --- a/users/fcuny/blog/Dockerfile +++ b/users/fcuny/blog/Dockerfile @@ -1,4 +1,4 @@ -FROM klakegg/hugo:0.83.1-ext-alpine-onbuild AS hugo +FROM klakegg/hugo:0.91.2-ext-alpine-onbuild AS hugo FROM pierrezemb/gostatic -- cgit 1.4.1 From 340454eea6d90bb1d05b30e5085adbb9e4315196 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 30 Jan 2022 19:38:58 -0800 Subject: note: update list of chipset for alder lake --- .../blog/content/notes/making-sense-intel-amd-cpus.org | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/content/notes/making-sense-intel-amd-cpus.org b/users/fcuny/blog/content/notes/making-sense-intel-amd-cpus.org index 2394085..60b433f 100644 --- a/users/fcuny/blog/content/notes/making-sense-intel-amd-cpus.org +++ b/users/fcuny/blog/content/notes/making-sense-intel-amd-cpus.org @@ -1,7 +1,7 @@ #+TITLE: Making sense of Intel and AMD CPUs naming #+DATE: <2021-12-29 Wed> #+TAGS[]: amd intel cpu -#+toc: t +#+toc: headlines 1 * Intel ** Core @@ -41,7 +41,16 @@ A processor with the *K* suffix is made with the an unlocked clock multiplier. W *** Sockets/Chipsets For the Alder Lake generation, the supported socket is the [[https://en.wikipedia.org/wiki/LGA_1700][LGA_1700]]. -For now the only supported chipset for Alder Lake is the [[https://ark.intel.com/content/www/us/en/ark/products/218833/intel-z690-chipset.html][z690]]. +For now only supported chipset for Alder Lake are: +| feature | [[https://ark.intel.com/content/www/us/en/ark/products/218833/intel-z690-chipset.html][z690]] | [[https://www.intel.com/content/www/us/en/products/sku/218831/intel-h670-chipset/specifications.html][h670]] | [[https://ark.intel.com/content/www/us/en/ark/products/218832/intel-b660-chipset.html][b660]] | [[https://www.intel.com/content/www/us/en/products/sku/218829/intel-h610-chipset/specifications.html][h610]] | +|-----------------------------+----------+----------+---------+------| +| P and E cores over clocking | yes | no | no | no | +| memory over clocking | yes | yes | yes | no | +| DMI 4 lanes | 8 | 8 | 4 | 4 | +| chipset PCIe 4.0 lanes | up to 12 | up to 12 | up to 6 | none | +| chipset PCIe 3.0 lanes | up to 16 | up to 12 | up to 8 | 8 | +| SATA 3.0 ports | up to 8 | up to 8 | 4 | 4 | + *** Alder Lake (12th generation) | model | p-cores | e-cores | GHz (base) | GHz (boosted) | TDP | |------------+---------+---------+------------+---------------+------| -- cgit 1.4.1 From 7ac496c860a8e6f57d3bab1207b1f677c9b6a835 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Wed, 16 Feb 2022 09:17:35 -0800 Subject: layout: improve readability and remove /notes The notes will be moved to a different site/repository, with their own style. Update the index page to make it more readable. Make the header more visible with fewer links. Add a footer, with links using SVG icons. --- users/fcuny/blog/config.toml | 22 +---- users/fcuny/blog/layouts/_default/baseof.html | 1 + users/fcuny/blog/layouts/index.html | 19 ++-- users/fcuny/blog/layouts/partials/footer.html | 32 +++++++ users/fcuny/blog/layouts/partials/header.html | 12 ++- users/fcuny/blog/static/css/custom.css | 120 +++++++++++++------------- 6 files changed, 110 insertions(+), 96 deletions(-) create mode 100644 users/fcuny/blog/layouts/partials/footer.html (limited to 'users/fcuny') diff --git a/users/fcuny/blog/config.toml b/users/fcuny/blog/config.toml index 1fe49bc..c47b946 100644 --- a/users/fcuny/blog/config.toml +++ b/users/fcuny/blog/config.toml @@ -20,32 +20,14 @@ enableGitInfo = true tags = "/tags/:slug/" [menu] - [[menu.main]] - identifier = "articles" - name = "blog" - title = "articles" - url = "/blog/" - weight = 110 - - [[menu.main]] - identifier = "notes" - name = "notes" - title = "notes" - url = "/notes/" - weight = 120 - [[menu.main]] identifier = "RSS" name = "RSS" - title = "RSS" + title = "~/blog/feed" url = "/feed.xml" weight = 130 [markup] - [markup.tableOfContents] - startLevel = 1 - endLevel = 3 - ordered = true [markup.highlight] anchorLineNos = false codeFences = false @@ -56,7 +38,7 @@ enableGitInfo = true lineNos = false lineNumbersInTable = false noClasses = true - style = "emacs" + style = "manni" tabWidth = 4 [mediaTypes."application/atom"] diff --git a/users/fcuny/blog/layouts/_default/baseof.html b/users/fcuny/blog/layouts/_default/baseof.html index 0c72fb1..410e2bc 100644 --- a/users/fcuny/blog/layouts/_default/baseof.html +++ b/users/fcuny/blog/layouts/_default/baseof.html @@ -6,5 +6,6 @@
    {{ block "main" . }}{{ end }}
    + {{- partial "footer.html" . -}} diff --git a/users/fcuny/blog/layouts/index.html b/users/fcuny/blog/layouts/index.html index 2ab8c40..38520ef 100644 --- a/users/fcuny/blog/layouts/index.html +++ b/users/fcuny/blog/layouts/index.html @@ -2,17 +2,18 @@
    -

    {{ .Site.Home.Title }}

    +

    I'm a Principal SRE, currently working at Roblox. Previously I worked at Twitter for over 7 years, and my main focus was on Twitter's compute platform.

    -

    I'm an engineer currently on a break. Previously I was a Site Reliability Engineer working on Twitter's compute platform.

    +

    My general interests are in building sustainable teams, improving the management and operation of large infrastructure, and work with different teams to implement best practices around reliability and security.

    -

    Contact

    - +

    Posts

    +
      + {{- $pages := where site.RegularPages "Type" "in" site.Params.mainSections }} + {{ range $pages }} + {{- $fmt := "2006-01-02" }} +
    • , {{ .Title }}
    • + {{ end }} +
    diff --git a/users/fcuny/blog/layouts/partials/footer.html b/users/fcuny/blog/layouts/partials/footer.html new file mode 100644 index 0000000..e2bf7ab --- /dev/null +++ b/users/fcuny/blog/layouts/partials/footer.html @@ -0,0 +1,32 @@ + diff --git a/users/fcuny/blog/layouts/partials/header.html b/users/fcuny/blog/layouts/partials/header.html index dede0ae..65900eb 100644 --- a/users/fcuny/blog/layouts/partials/header.html +++ b/users/fcuny/blog/layouts/partials/header.html @@ -1,12 +1,10 @@
    -
    diff --git a/users/fcuny/blog/static/css/custom.css b/users/fcuny/blog/static/css/custom.css index ae6d674..70ce618 100644 --- a/users/fcuny/blog/static/css/custom.css +++ b/users/fcuny/blog/static/css/custom.css @@ -1,37 +1,40 @@ body { font-family: sans-serif; - font-size: 1.125em; - line-height: 1.5; - color: #37474f; + font-size: 1em; + line-height: 1.8em; + color: #0e0e0b; margin: 1em auto; padding: 0 0.55em; - max-width: 45rem; -} - -@media screen and (min-width:58rem) { - body, - main { - max-width:calc(45rem + 15rem); - } - main { - display: flex; - } + max-width: 50rem; } h1 { + color: #0e0e0b; font-size: 2rem; margin-top: 1em; margin-bottom: 0.34em; } -h2 {margin-top: 1.25em; margin-bottom: 0.41em} -h3 {margin-top: 1.5em; margin-bottom: 0.5em} +h2, h3 { + border-bottom: 1px solid #eee; + font-style: italic; +} +h2 { + margin-top: 1.25em; + margin-bottom: 0.41em; + font-size: 1.4rem; +} +h3 { + margin-top: 1.5em; + margin-bottom: 0.5em; + font-size: 1.2rem; +} hr{ color:#000111; background-color:#000111; border:none; - height:2px + height:1px } a { @@ -64,10 +67,12 @@ p code { color: black; background-color: #eee; padding: 0 0.2rem; + font-size: 1.1em; } pre { font-family: monospace; + font-size: 1.1em; margin: 0; word-wrap: normal; padding: 0.8em; @@ -130,20 +135,15 @@ blockquote { } nav { - width: 100%; padding-right: 10px; + font-size: 1.4em; display: flex; + font-family: monospace; justify-content: space-between; align-items: center; padding-top: 0.5rem; } -@media screen and (min-width:58rem) { - nav { - max-width: calc(45rem + 15rem); - } -} - .nav-links { list-style: none; display: flex; @@ -151,51 +151,51 @@ nav { .navbar a { display: inline-block; - padding-right: 10px; + text-decoration: none; +} + +.navbar a:hover { + background-color: #b72d2d; + color: #fafafa; + text-decoration: none; +} + +.nav-bold { + font-weight: 700; + color: #b72d2d; + text-decoration: none; } article { - max-width: 45rem; + text-align: justify; } -#toc {display: none} +.post-permalink { + list-style: none; + margin-left: -20px; +} -#toc_small { - font-size: 0.9rem; - margin-bottom: 2rem; - margin-top: 2rem; +.post-date { + font-family: monospace; + font-weight: 400; + font-size: 1.1em; } -@media screen and (min-width:58rem) { - #toc_small {display: none;} + +footer { + border-top: 2px solid #eee; + margin-top: 2em; + display: flex; + flex-direction: row; + justify-content: left; + align-items: left; } -summary { - display:flex; - flex-direction:column; +footer a, footer a:link, footer a:focus, footer a:active, footer a:hover { + color: black; + text-decoration: none; + padding: 5px; } -#TableOfContents > ul, #TableOfContents > ul > li > ul { - list-style: none; - margin: 0; - padding: 0; -} - -#TableOfContents li {margin-bottom: 1rem;} - -@media screen and (min-width:58rem) { - #toc { - padding-left: 1rem; - padding-top: 4.5rem; - font-size: 0.9rem; - display:block; - position:sticky; - top:0; - align-self:flex-start; - max-width:15rem; - z-index:1; - } - #TableOfContents { - border-left: 3px solid #eee; - padding-left: 1rem; - } +footer a:not(:first-child) { + margin-left: 15px; } -- cgit 1.4.1 From 5f41fd8b8b7cc2db152d4c353ce7da4c75e2dcf2 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 1 May 2022 13:35:46 -0700 Subject: build: slowly moving to nix Add a `flake.nix' configuration to pull the required dependencies and run the server. Remove a few targets from the Makefile and move the deployment part to a script. --- users/fcuny/blog/.envrc | 1 + users/fcuny/blog/Makefile | 17 +---------------- users/fcuny/blog/flake.lock | 26 ++++++++++++++++++++++++++ users/fcuny/blog/flake.nix | 19 +++++++++++++++++++ users/fcuny/blog/scripts/deploy.sh | 10 ++++++++++ 5 files changed, 57 insertions(+), 16 deletions(-) create mode 100644 users/fcuny/blog/.envrc create mode 100644 users/fcuny/blog/flake.lock create mode 100644 users/fcuny/blog/flake.nix create mode 100755 users/fcuny/blog/scripts/deploy.sh (limited to 'users/fcuny') diff --git a/users/fcuny/blog/.envrc b/users/fcuny/blog/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/users/fcuny/blog/.envrc @@ -0,0 +1 @@ +use flake diff --git a/users/fcuny/blog/Makefile b/users/fcuny/blog/Makefile index 5414dde..e2731d4 100644 --- a/users/fcuny/blog/Makefile +++ b/users/fcuny/blog/Makefile @@ -5,22 +5,7 @@ DOCKER_IMAGE_REF := $(shell git rev-parse HEAD) DOCKERFILE := Dockerfile PROJECT_DIR := $(realpath $(CURDIR)) -.PHONY: server deploy docker-build docker-run worktree-clean - -server: - @echo "Running hugo server ..." - hugo server - -worktree-clean: - git diff --exit-code - git diff --staged --exit-code - -deploy: worktree-clean docker-build - @echo "Deploying to fly ..." - flyctl deploy - @git tag -a --message $$(flyctl info -j |jq -r '.App | "fcuny.net/v\(.Version)"') $$(flyctl info -j |jq -r '.App | "fcuny.net/v\(.Version)"') - @git push origin --all - @git push origin --tags +.PHONY: docker-build docker-run docker-build: @echo "Building Docker image ..." diff --git a/users/fcuny/blog/flake.lock b/users/fcuny/blog/flake.lock new file mode 100644 index 0000000..d7426e1 --- /dev/null +++ b/users/fcuny/blog/flake.lock @@ -0,0 +1,26 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1651345462, + "narHash": "sha256-4wf9sMUKGBjC2jWnUwG52ychtXRKlS3LfX/HEY6DjhM=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "870249df2cc640e2278cd0bc599ebbb246b00802", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/users/fcuny/blog/flake.nix b/users/fcuny/blog/flake.nix new file mode 100644 index 0000000..59ef578 --- /dev/null +++ b/users/fcuny/blog/flake.nix @@ -0,0 +1,19 @@ +{ + description = "Franck Cuny's personal website."; + + inputs = { nixpkgs.url = "github:nixos/nixpkgs"; }; + + outputs = { self, nixpkgs }: + let pkgs = nixpkgs.legacyPackages.x86_64-linux; + in { + defaultApp.x86_64-linux = self.apps.server; + apps.server = pkgs.writers.writeBashBin "server" '' + set -e + set -o pipefail + PATH=${pkgs.lib.makeBinPath [ pkgs.hugo pkgs.git ]} + hugo server + ''; + devShell.x86_64-linux = + pkgs.mkShell { buildInputs = with pkgs; [ hugo flyctl git ]; }; + }; +} diff --git a/users/fcuny/blog/scripts/deploy.sh b/users/fcuny/blog/scripts/deploy.sh new file mode 100755 index 0000000..82919c6 --- /dev/null +++ b/users/fcuny/blog/scripts/deploy.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +git diff --exit-code +git diff --staged --exit-code + +VERSION=$(flyctl info -j |jq -r '.App | "fcuny.net/v\(.Version)"') + +git tag -a --message ${VERSION} ${VERSION} +git push origin --all +git push origin --tags -- cgit 1.4.1 From 3ed3ffba2362aeed965d596252885a69db67b5c9 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 1 May 2022 13:37:05 -0700 Subject: content: remove some notes They are at https://notes.fcuny.net now. --- .../content/notes/containerd-to-firecracker.org | 568 --------------------- .../content/notes/making-sense-intel-amd-cpus.org | 131 ----- .../fcuny/blog/content/notes/stuff-about-pcie.org | 196 ------- users/fcuny/blog/content/notes/working-with-go.org | 264 ---------- 4 files changed, 1159 deletions(-) delete mode 100644 users/fcuny/blog/content/notes/containerd-to-firecracker.org delete mode 100644 users/fcuny/blog/content/notes/making-sense-intel-amd-cpus.org delete mode 100644 users/fcuny/blog/content/notes/stuff-about-pcie.org delete mode 100644 users/fcuny/blog/content/notes/working-with-go.org (limited to 'users/fcuny') diff --git a/users/fcuny/blog/content/notes/containerd-to-firecracker.org b/users/fcuny/blog/content/notes/containerd-to-firecracker.org deleted file mode 100644 index 554771d..0000000 --- a/users/fcuny/blog/content/notes/containerd-to-firecracker.org +++ /dev/null @@ -1,568 +0,0 @@ -#+TITLE: containerd to firecracker -#+DATE: <2021-05-15 Sat> -#+TAGS[]: linux firecracker containerd go -#+toc: t - -fly.io had an [[https://fly.io/blog/docker-without-docker/][interesting article]] about how they use docker images to create VMs for =firecracker=. - -They describe the process as follow: - -1. Pull a container from a registry -2. Create a loop device to store the container's filesystem on -3. Unpack the container into the mounted loop device -4. Create a second block device and inject init, kernel, configuration and other stuff -5. Attach persistent volumes (if any) -6. Create a TAP device and configure it -7. Hand it off to Firecracker and boot that thing - -That's pretty detailed, and I'm curious how difficult it is to implement this. I've been meaning to look into Firecracker for a while and into containers'd API, so this is a perfect opportunity to get started. The code is available [[https://git.fcuny.net/fcuny/containerd-to-vm][here]]. - -* #1 Pull a container from a registry with =containerd= -=containerd= has a pretty [[https://pkg.go.dev/github.com/containerd/containerd][detailed documentation]]. From the main page we can see the following example to create a client. -#+begin_src go -import ( - "github.com/containerd/containerd" - "github.com/containerd/containerd/cio" -) - - -func main() { - client, err := containerd.New("/run/containerd/containerd.sock") - defer client.Close() -} -#+end_src - -And pulling an image is also pretty straightforward: -#+begin_src go -image, err := client.Pull(context, "docker.io/library/redis:latest") -#+end_src - -The =Pull= method returns an [[https://pkg.go.dev/github.com/containerd/containerd@v1.4.4/images#Image][=Image=]] and there's a few methods associated with it. - -As =containerd= has namespaces, it's possible to specify the namespace we want to use when working with the API: -#+begin_src go -ctx := namespaces.WithNamespace(context.Background(), "c2vm") -image, err := client.Pull(ctx, "docker.io/library/redis:latest") -#+end_src - -The image will now be stored in the =c2vm= namespace. We can verify this with: -#+begin_src sh -; sudo ctr -n c2vm images ls -q -docker.io/library/redis:latest -#+end_src - -* #2 Create a loop device to store the container's filesystem on -This is going to be pretty straightforward. To create a loop device we need to: -1. pre-allocate space to a file -2. convert that file to some format -3. mount it to some destination - -There's two commons ways to pre-allocate space to a file: =dd= and =fallocate= (there's likely way more ways to do this). I'll go with =fallocate= for this example. - -First, to be safe, we create a temporary file, and use =renameio= to handle the renaming (I recommend reading the doc of the module). - -#+begin_src go -f, err := renameio.TempFile("", rawFile) -if err != nil { - return err -} -defer f.Cleanup() -#+end_src - -Now to do the pre-allocation (we're making an assumption here that 2GB is enough, we can likely check what's the size of the container before doing this): -#+begin_src go -command := exec.Command("fallocate", "-l", "2G", f.Name()) -if err := command.Run(); err != nil { - return fmt.Errorf("fallocate error: %s", err) -} -#+end_src - -We can now convert that file to ext4: -#+begin_src go -command = exec.Command("mkfs.ext4", "-F", f.Name()) -if err := command.Run(); err != nil { - return fmt.Errorf("mkfs.ext4 error: %s", err) -} -#+end_src - -Now we can rename safely the temporary file to the proper file we want: -#+begin_src go -f.CloseAtomicallyReplace() -#+end_src - -And to mount that file -#+begin_src go -command = exec.Command("mount", "-o", "loop", rawFile, mntDir) -if err := command.Run(); err != nil { - return fmt.Errorf("mount error: %s", err) -} -#+end_src -* #3 Unpack the container into the mounted loop device -Extracting the container using =containerd= is pretty simple. Here's the function that I use: -#+begin_src go -func extract(ctx context.Context, client *containerd.Client, image containerd.Image, mntDir string) error { - manifest, err := images.Manifest(ctx, client.ContentStore(), image.Target(), platform) - if err != nil { - log.Fatalf("failed to get the manifest: %v\n", err) - } - - for _, desc := range manifest.Layers { - log.Printf("extracting layer %s\n", desc.Digest.String()) - layer, err := client.ContentStore().ReaderAt(ctx, desc) - if err != nil { - return err - } - if err := archive.Untar(content.NewReader(layer), mntDir, &archive.TarOptions{NoLchown: true}); err != nil { - return err - } - } - - return nil -} -#+end_src - -Calling =images.Manifest= returns the [[https://github.com/opencontainers/image-spec/blob/master/manifest.md][manifest]] from the image. What we care here are the list of layers. Here I'm making a number of assumptions regarding their type (we should be checking the media type first). We read the layers and extract them to the mounted path. -* #4 Create a second block device and inject other stuff -Here I'm going to deviate a bit. I will not create a second loop device, and I will not inject a kernel. In their article, they provided a link to a snapshot of their =init= process (https://github.com/superfly/init-snapshot). In order to keep this simple, our init is going to be a shell script composed of the content of the entry point of the container. We're also going to add a few extra files to container (=/etc/hosts= and =/etc/resolv.conf=). - -Finally, since we've pre-allocated 2GB for that container, and we likely don't need that much, we're also going to resize the image. -** Add init -Let's refer to the [[https://github.com/opencontainers/image-spec/blob/master/config.md][specification for the config]]. The elements that are of interest to me are: -- =Env=, which is array of strings. They contain the environment variables that likely we need to run the program -- =Cmd=, which is also an array of strings. If there's no entry point provided, this is what is used. - -At this point, for this experiment, I'm going to ignore exposed ports, working directory, and the user. - -First we need to read the config from the container. This is easily done: -#+begin_src go -config, err := images.Config(ctx, client.ContentStore(), image.Target(), platform) -if err != nil { - return err -} -#+end_src - -This needs to be read and decoded: -#+begin_src go -configBlob, err := content.ReadBlob(ctx, client.ContentStore(), config) -var imageSpec ocispec.Image -json.Unmarshal(configBlob, &imageSpec) -#+end_src - -=init= is the first process started by Linux during boot. On a regular Linux desktop you likely have a symbolic link from =/usr/bin/init= to =/usr/lib/systemd/systemd=, since most distributions have switched to =systemd=. For my use case however, I want to run a single process, and I want it to be the one from the container. For this we can create a simple shell script inside the container (the location does not matter for now) with the environment variables and the command. - -Naively, this can be done like this: -#+begin_src go -initPath := filepath.Join(mntDir, "init.sh") -f, err := renameio.TempFile("", initPath) -if err != nil { - return err -} -defer f.Cleanup() - -writer := bufio.NewWriter(f) -fmt.Fprintf(writer, "#!/bin/sh\n") -for _, env := range initEnvs { - fmt.Fprintf(writer, "export %s\n", env) -} -fmt.Fprintf(writer, "%s\n", initCmd) -writer.Flush() - -f.CloseAtomicallyReplace() - -mode := int(0755) -os.Chmod(initPath, os.FileMode(mode)) -#+end_src - -We're once again creating a temporary file with =renamio=, and we're writing our shell scripts, one line at a time. We only need to make sure this executable. -** extra files -Once we have our init file, I also want to add a few extra files: =/etc/hosts= and =/etc/resolv.conf=. This files are not always present, since they can be injected by other systems. I also want to make sure that DNS resolutions are done using my own DNS server. -** resize the image -We've pre-allocated 2GB for the image, and it's likely we don't need as much space. We can do this by running =e2fsck= and =resize2fs= once we're done manipulating the image. - -Within a function, we can do the following: -#+begin_src go -command := exec.Command("/usr/bin/e2fsck", "-p", "-f", rawFile) -if err := command.Run(); err != nil { - return fmt.Errorf("e2fsck error: %s", err) -} - -command = exec.Command("resize2fs", "-M", rawFile) -if err := command.Run(); err != nil { - return fmt.Errorf("resize2fs error: %s", err) -} -#+end_src - -I'm using =docker.io/library/redis:latest= for my test, and I end up with the following size for the image: -#+begin_src bash --rw------- 1 root root 216M Apr 22 14:50 /tmp/fcuny.img -#+end_src -** Kernel -We're going to need a kernel to run that VM. In my case I've decided to go with version 5.8, and build a custom kernel. If you are not familiar with the process, the firecracker team has [[https://github.com/firecracker-microvm/firecracker/blob/main/docs/rootfs-and-kernel-setup.md#creating-a-kernel-image][documented how to do this]]. In my case all I had to do was: -#+begin_src sh -git clone https://github.com/torvalds/linux.git linux.git -cd linux.git -git checkout v5.8 -curl -o .config -s https://github.com/firecracker-microvm/firecracker/blob/main/resources/microvm-kernel-x86_64.config -make menuconfig -make vmlinux -j8 -#+end_src - -Note that they also have a pretty [[https://github.com/firecracker-microvm/firecracker/blob/main/docs/prod-host-setup.md][good documentation for production]]. -* #5 Attach persistent volumes (if any) -I'm going to skip that step for now. -* #6 Create a TAP device and configure it -We're going to need a network for that VM (otherwise it might be a bit boring). -There's a few solutions that we can take: -1. create the TAP device -2. delegate all that work to a [[https://github.com/containernetworking/cni][CNI]] - -I've decided to use the CNI approach [[https://github.com/firecracker-microvm/firecracker-go-sdk#cni][documented in the Go's SDK]]. For this to work we need to install the =tc-redirect-tap= CNI plugin (available at https://github.com/awslabs/tc-redirect-tap). - -Based on that documentation, I'll start with the following configuration in =etc/cni/conf.d/50-c2vm.conflist=: -#+begin_src json -{ - "name": "c2vm", - "cniVersion": "0.4.0", - "plugins": [ - { - "type": "bridge", - "bridge": "c2vm-br", - "isDefaultGateway": true, - "forceAddress": false, - "ipMasq": true, - "hairpinMode": true, - "mtu": 1500, - "ipam": { - "type": "host-local", - "subnet": "192.168.128.0/24", - "resolvConf": "/etc/resolv.conf" - } - }, - { - "type": "firewall" - }, - { - "type": "tc-redirect-tap" - } - ] -} -#+end_src -* #7 Hand it off to Firecracker and boot that thing -Now that we have all the components, we need to boot that VM. Since I've been working with Go so far, I'll also use the [[https://github.com/firecracker-microvm/firecracker-go-sdk][Go SDK]] to manage and start the VM. - -For this we need the firecracker binary, which we can [[https://github.com/firecracker-microvm/firecracker/releases][find on GitHub]]. - -The first thing is to configure the list of devices. In our case we will have a single device, the boot drive that we've created in the previous step. -#+begin_src go -devices := make([]models.Drive, 1) -devices[0] = models.Drive{ - DriveID: firecracker.String("1"), - PathOnHost: &rawImage, - IsRootDevice: firecracker.Bool(true), - IsReadOnly: firecracker.Bool(false), -} -#+end_src - -The next step is to configure the VM: -#+begin_src go -fcCfg := firecracker.Config{ - LogLevel: "debug", - SocketPath: firecrackerSock, - KernelImagePath: linuxKernel, - KernelArgs: "console=ttyS0 reboot=k panic=1 acpi=off pci=off i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd init=/init.sh random.trust_cpu=on", - Drives: devices, - MachineCfg: models.MachineConfiguration{ - VcpuCount: firecracker.Int64(1), - CPUTemplate: models.CPUTemplate("C3"), - HtEnabled: firecracker.Bool(true), - MemSizeMib: firecracker.Int64(512), - }, - NetworkInterfaces: []firecracker.NetworkInterface{ - { - CNIConfiguration: &firecracker.CNIConfiguration{ - NetworkName: "c2vm", - IfName: "eth0", - }, - }, - }, -} -#+end_src - -Finally we can create the command to start and run the VM: -#+begin_src go -command := firecracker.VMCommandBuilder{}. - WithBin(firecrackerBinary). - WithSocketPath(fcCfg.SocketPath). - WithStdin(os.Stdin). - WithStdout(os.Stdout). - WithStderr(os.Stderr). - Build(ctx) -machineOpts = append(machineOpts, firecracker.WithProcessRunner(command)) -m, err := firecracker.NewMachine(vmmCtx, fcCfg, machineOpts...) -if err != nil { - panic(err) -} - -if err := m.Start(vmmCtx); err != nil { - panic(err) -} -defer m.StopVMM() - -if err := m.Wait(vmmCtx); err != nil { - panic(err) -} -#+end_src - -The end result: -#+begin_src -; sudo ./c2vm -container docker.io/library/redis:latest -firecracker-binary ./hack/firecracker/firecracker-v0.24.3-x86_64 -linux-kernel ./hack/linux/my-linux.bin -out /tmp/redis.img -2021/05/15 14:12:59 pulled docker.io/library/redis:latest (38690247 bytes) -2021/05/15 14:13:00 mounted /tmp/redis.img on /tmp/c2vm026771514 -2021/05/15 14:13:00 extracting layer sha256:69692152171afee1fd341febc390747cfca2ff302f2881d8b394e786af605696 -2021/05/15 14:13:00 extracting layer sha256:a4a46f2fd7e06fab84b4e78eb2d1b6d007351017f9b18dbeeef1a9e7cf194e00 -2021/05/15 14:13:00 extracting layer sha256:bcdf6fddc3bdaab696860eb0f4846895c53a3192c9d7bf8d2275770ea8073532 -2021/05/15 14:13:01 extracting layer sha256:b7e9b50900cc06838c44e0fc5cbebe5c0b3e7f70c02f32dd754e1aa6326ed566 -2021/05/15 14:13:01 extracting layer sha256:5f3030c50d85a9d2f70adb610b19b63290c6227c825639b227ddc586f86d1c76 -2021/05/15 14:13:01 extracting layer sha256:63dae8e0776cdbd63909fbd9c047c1615a01cb21b73efa87ae2feed680d3ffa1 -2021/05/15 14:13:01 init script created -2021/05/15 14:13:01 umount /tmp/c2vm026771514 -INFO[0003] Called startVMM(), setting up a VMM on firecracker.sock -INFO[0003] VMM logging disabled. -INFO[0003] VMM metrics disabled. -INFO[0003] refreshMachineConfiguration: [GET /machine-config][200] getMachineConfigurationOK &{CPUTemplate:C3 HtEnabled:0xc0004e6753 MemSizeMib:0xc0004e6748 VcpuCount:0xc0004e6740} -INFO[0003] PutGuestBootSource: [PUT /boot-source][204] putGuestBootSourceNoContent -INFO[0003] Attaching drive /tmp/redis.img, slot 1, root true. -INFO[0003] Attached drive /tmp/redis.img: [PUT /drives/{drive_id}][204] putGuestDriveByIdNoContent -INFO[0003] Attaching NIC tap0 (hwaddr 9e:72:c7:04:6b:80) at index 1 -INFO[0003] startInstance successful: [PUT /actions][204] createSyncActionNoContent -[ 0.000000] Linux version 5.8.0 (fcuny@nas) (gcc (Debian 8.3.0-6) 8.3.0, GNU ld (GNU Binutils for Debian) 2.31.1) #1 SMP Mon Apr 12 20:07:40 PDT 2021 -[ 0.000000] Command line: i8042.dumbkbd ip=192.168.128.9::192.168.128.1:255.255.255.0:::off::: console=ttyS0 reboot=k panic=1 acpi=off pci=off i8042.noaux i8042.nomux i8042.nopnp init=/init.sh random.trust_cpu=on root=/dev/vda rw virtio_mmio.device=4K@0xd0000000:5 virtio_mmio.device=4K@0xd0001000:6 -[ 0.000000] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers' -[ 0.000000] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers' -[ 0.000000] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers' -[ 0.000000] x86/fpu: xstate_offset[2]: 576, xstate_sizes[2]: 256 -[ 0.000000] x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, using 'standard' format. -[ 0.000000] BIOS-provided physical RAM map: -[ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable -[ 0.000000] BIOS-e820: [mem 0x0000000000100000-0x000000001fffffff] usable -[ 0.000000] NX (Execute Disable) protection: active -[ 0.000000] DMI not present or invalid. -[ 0.000000] Hypervisor detected: KVM -[ 0.000000] kvm-clock: Using msrs 4b564d01 and 4b564d00 -[ 0.000000] kvm-clock: cpu 0, msr 2401001, primary cpu clock -[ 0.000000] kvm-clock: using sched offset of 11918596 cycles -[ 0.000005] clocksource: kvm-clock: mask: 0xffffffffffffffff max_cycles: 0x1cd42e4dffb, max_idle_ns: 881590591483 ns -[ 0.000011] tsc: Detected 1190.400 MHz processor -[ 0.000108] last_pfn = 0x20000 max_arch_pfn = 0x400000000 -[ 0.000151] Disabled -[ 0.000156] x86/PAT: MTRRs disabled, skipping PAT initialization too. -[ 0.000166] CPU MTRRs all blank - virtualized system. -[ 0.000170] x86/PAT: Configuration [0-7]: WB WT UC- UC WB WT UC- UC -[ 0.000201] found SMP MP-table at [mem 0x0009fc00-0x0009fc0f] -[ 0.000257] check: Scanning 1 areas for low memory corruption -[ 0.000364] No NUMA configuration found -[ 0.000365] Faking a node at [mem 0x0000000000000000-0x000000001fffffff] -[ 0.000370] NODE_DATA(0) allocated [mem 0x1ffde000-0x1fffffff] -[ 0.000490] Zone ranges: -[ 0.000493] DMA [mem 0x0000000000001000-0x0000000000ffffff] -[ 0.000494] DMA32 [mem 0x0000000001000000-0x000000001fffffff] -[ 0.000495] Normal empty -[ 0.000497] Movable zone start for each node -[ 0.000500] Early memory node ranges -[ 0.000501] node 0: [mem 0x0000000000001000-0x000000000009efff] -[ 0.000502] node 0: [mem 0x0000000000100000-0x000000001fffffff] -[ 0.000510] Zeroed struct page in unavailable ranges: 98 pages -[ 0.000511] Initmem setup node 0 [mem 0x0000000000001000-0x000000001fffffff] -[ 0.004990] Intel MultiProcessor Specification v1.4 -[ 0.004995] MPTABLE: OEM ID: FC -[ 0.004995] MPTABLE: Product ID: 000000000000 -[ 0.004996] MPTABLE: APIC at: 0xFEE00000 -[ 0.005007] Processor #0 (Bootup-CPU) -[ 0.005039] IOAPIC[0]: apic_id 2, version 17, address 0xfec00000, GSI 0-23 -[ 0.005041] Processors: 1 -[ 0.005042] TSC deadline timer available -[ 0.005044] smpboot: Allowing 1 CPUs, 0 hotplug CPUs -[ 0.005060] KVM setup pv remote TLB flush -[ 0.005072] KVM setup pv sched yield -[ 0.005078] PM: hibernation: Registered nosave memory: [mem 0x00000000-0x00000fff] -[ 0.005079] PM: hibernation: Registered nosave memory: [mem 0x0009f000-0x000fffff] -[ 0.005081] [mem 0x20000000-0xffffffff] available for PCI devices -[ 0.005082] Booting paravirtualized kernel on KVM -[ 0.005084] clocksource: refined-jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645519600211568 ns -[ 0.005087] setup_percpu: NR_CPUS:128 nr_cpumask_bits:128 nr_cpu_ids:1 nr_node_ids:1 -[ 0.006381] percpu: Embedded 44 pages/cpu s143360 r8192 d28672 u2097152 -[ 0.006404] KVM setup async PF for cpu 0 -[ 0.006410] kvm-stealtime: cpu 0, msr 1f422080 -[ 0.006420] Built 1 zonelists, mobility grouping on. Total pages: 128905 -[ 0.006420] Policy zone: DMA32 -[ 0.006422] Kernel command line: i8042.dumbkbd ip=192.168.128.9::192.168.128.1:255.255.255.0:::off::: console=ttyS0 reboot=k panic=1 acpi=off pci=off i8042.noaux i8042.nomux i8042.nopnp init=/init.sh random.trust_cpu=on root=/dev/vda rw virtio_mmio.device=4K@0xd0000000:5 virtio_mmio.device=4K@0xd0001000:6 -[ 0.006858] Dentry cache hash table entries: 65536 (order: 7, 524288 bytes, linear) -[ 0.007003] Inode-cache hash table entries: 32768 (order: 6, 262144 bytes, linear) -[ 0.007047] mem auto-init: stack:off, heap alloc:off, heap free:off -[ 0.007947] Memory: 491940K/523896K available (10243K kernel code, 629K rwdata, 1860K rodata, 1408K init, 6048K bss, 31956K reserved, 0K cma-reserved) -[ 0.007980] random: get_random_u64 called from __kmem_cache_create+0x3d/0x540 with crng_init=0 -[ 0.008053] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1 -[ 0.008146] rcu: Hierarchical RCU implementation. -[ 0.008147] rcu: RCU restricting CPUs from NR_CPUS=128 to nr_cpu_ids=1. -[ 0.008151] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies. -[ 0.008152] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1 -[ 0.008170] NR_IRQS: 4352, nr_irqs: 48, preallocated irqs: 16 -[ 0.008373] random: crng done (trusting CPU's manufacturer) -[ 0.008430] Console: colour dummy device 80x25 -[ 0.052276] printk: console [ttyS0] enabled -[ 0.052685] APIC: Switch to symmetric I/O mode setup -[ 0.053288] x2apic enabled -[ 0.053705] Switched APIC routing to physical x2apic. -[ 0.054213] KVM setup pv IPIs -[ 0.055559] clocksource: tsc-early: mask: 0xffffffffffffffff max_cycles: 0x1128af0325d, max_idle_ns: 440795261011 ns -[ 0.056516] Calibrating delay loop (skipped) preset value.. 2380.80 BogoMIPS (lpj=4761600) -[ 0.057259] pid_max: default: 32768 minimum: 301 -[ 0.057726] LSM: Security Framework initializing -[ 0.058176] SELinux: Initializing. -[ 0.058556] Mount-cache hash table entries: 1024 (order: 1, 8192 bytes, linear) -[ 0.059221] Mountpoint-cache hash table entries: 1024 (order: 1, 8192 bytes, linear) -[ 0.060382] x86/cpu: User Mode Instruction Prevention (UMIP) activated -[ 0.060510] Last level iTLB entries: 4KB 0, 2MB 0, 4MB 0 -[ 0.060510] Last level dTLB entries: 4KB 0, 2MB 0, 4MB 0, 1GB 0 -[ 0.060510] Spectre V1 : Mitigation: usercopy/swapgs barriers and __user pointer sanitization -[ 0.060510] Spectre V2 : Mitigation: Enhanced IBRS -[ 0.060510] Spectre V2 : Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch -[ 0.060510] Spectre V2 : mitigation: Enabling conditional Indirect Branch Prediction Barrier -[ 0.060510] Speculative Store Bypass: Mitigation: Speculative Store Bypass disabled via prctl and seccomp -[ 0.060510] Freeing SMP alternatives memory: 32K -[ 0.060510] smpboot: CPU0: Intel(R) Xeon(R) Processor @ 1.20GHz (family: 0x6, model: 0x3e, stepping: 0x4) -[ 0.060510] Performance Events: unsupported p6 CPU model 62 no PMU driver, software events only. -[ 0.060510] rcu: Hierarchical SRCU implementation. -[ 0.060510] smp: Bringing up secondary CPUs ... -[ 0.060510] smp: Brought up 1 node, 1 CPU -[ 0.060510] smpboot: Max logical packages: 1 -[ 0.060523] smpboot: Total of 1 processors activated (2380.80 BogoMIPS) -[ 0.061338] devtmpfs: initialized -[ 0.061710] x86/mm: Memory block size: 128MB -[ 0.062341] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns -[ 0.063245] futex hash table entries: 256 (order: 2, 16384 bytes, linear) -[ 0.063946] thermal_sys: Registered thermal governor 'fair_share' -[ 0.063946] thermal_sys: Registered thermal governor 'step_wise' -[ 0.064522] thermal_sys: Registered thermal governor 'user_space' -[ 0.065313] NET: Registered protocol family 16 -[ 0.066398] DMA: preallocated 128 KiB GFP_KERNEL pool for atomic allocations -[ 0.067057] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA pool for atomic allocations -[ 0.067778] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations -[ 0.068506] audit: initializing netlink subsys (disabled) -[ 0.068708] cpuidle: using governor ladder -[ 0.069097] cpuidle: using governor menu -[ 0.070636] audit: type=2000 audit(1621113181.800:1): state=initialized audit_enabled=0 res=1 -[ 0.076346] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages -[ 0.077007] ACPI: Interpreter disabled. -[ 0.077445] SCSI subsystem initialized -[ 0.077812] pps_core: LinuxPPS API ver. 1 registered -[ 0.078277] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti -[ 0.079206] PTP clock support registered -[ 0.079741] NetLabel: Initializing -[ 0.080111] NetLabel: domain hash size = 128 -[ 0.080529] NetLabel: protocols = UNLABELED CIPSOv4 CALIPSO -[ 0.081113] NetLabel: unlabeled traffic allowed by default -[ 0.082072] clocksource: Switched to clocksource kvm-clock -[ 0.082715] VFS: Disk quotas dquot_6.6.0 -[ 0.083123] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes) -[ 0.083855] pnp: PnP ACPI: disabled -[ 0.084510] NET: Registered protocol family 2 -[ 0.084718] tcp_listen_portaddr_hash hash table entries: 256 (order: 0, 4096 bytes, linear) -[ 0.085602] TCP established hash table entries: 4096 (order: 3, 32768 bytes, linear) -[ 0.086365] TCP bind hash table entries: 4096 (order: 4, 65536 bytes, linear) -[ 0.087025] TCP: Hash tables configured (established 4096 bind 4096) -[ 0.087749] UDP hash table entries: 256 (order: 1, 8192 bytes, linear) -[ 0.088481] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear) -[ 0.089261] NET: Registered protocol family 1 -[ 0.090395] virtio-mmio: Registering device virtio-mmio.0 at 0xd0000000-0xd0000fff, IRQ 5. -[ 0.091388] virtio-mmio: Registering device virtio-mmio.1 at 0xd0001000-0xd0001fff, IRQ 6. -[ 0.092222] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x1128af0325d, max_idle_ns: 440795261011 ns -[ 0.093322] clocksource: Switched to clocksource tsc -[ 0.093824] platform rtc_cmos: registered platform RTC device (no PNP device found) -[ 0.094618] check: Scanning for low memory corruption every 60 seconds -[ 0.095394] Initialise system trusted keyrings -[ 0.095836] Key type blacklist registered -[ 0.096427] workingset: timestamp_bits=36 max_order=17 bucket_order=0 -[ 0.097849] squashfs: version 4.0 (2009/01/31) Phillip Lougher -[ 0.107488] Key type asymmetric registered -[ 0.107905] Asymmetric key parser 'x509' registered -[ 0.108409] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252) -[ 0.109435] Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled -[ 0.110116] serial8250: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A -[ 0.111877] loop: module loaded -[ 0.112426] virtio_blk virtio0: [vda] 441152 512-byte logical blocks (226 MB/215 MiB) -[ 0.113229] vda: detected capacity change from 0 to 225869824 -[ 0.114143] Loading iSCSI transport class v2.0-870. -[ 0.114753] iscsi: registered transport (tcp) -[ 0.115162] tun: Universal TUN/TAP device driver, 1.6 -[ 0.115955] i8042: PNP detection disabled -[ 0.116498] serio: i8042 KBD port at 0x60,0x64 irq 1 -[ 0.117089] input: AT Raw Set 2 keyboard as /devices/platform/i8042/serio0/input/input0 -[ 0.117932] intel_pstate: CPU model not supported -[ 0.118448] hid: raw HID events driver (C) Jiri Kosina -[ 0.119090] Initializing XFRM netlink socket -[ 0.119555] NET: Registered protocol family 10 -[ 0.120285] Segment Routing with IPv6 -[ 0.120812] NET: Registered protocol family 17 -[ 0.121350] Bridge firewalling registered -[ 0.122026] NET: Registered protocol family 40 -[ 0.122515] IPI shorthand broadcast: enabled -[ 0.122961] sched_clock: Marking stable (72512224, 48198862)->(137683636, -16972550) -[ 0.123796] registered taskstats version 1 -[ 0.124203] Loading compiled-in X.509 certificates -[ 0.125355] Loaded X.509 cert 'Build time autogenerated kernel key: 6203e6adc37b712d3b220a26b38f3d31311d5966' -[ 0.126355] Key type ._fscrypt registered -[ 0.126736] Key type .fscrypt registered -[ 0.127109] Key type fscrypt-provisioning registered -[ 0.127657] Key type encrypted registered -[ 0.144629] IP-Config: Complete: -[ 0.144968] device=eth0, hwaddr=9e:72:c7:04:6b:80, ipaddr=192.168.128.9, mask=255.255.255.0, gw=192.168.128.1 -[ 0.146044] host=192.168.128.9, domain=, nis-domain=(none) -[ 0.146604] bootserver=255.255.255.255, rootserver=255.255.255.255, rootpath= -[ 0.148347] EXT4-fs (vda): mounted filesystem with ordered data mode. Opts: (null) -[ 0.149098] VFS: Mounted root (ext4 filesystem) on device 254:0. -[ 0.149761] devtmpfs: mounted -[ 0.150340] Freeing unused decrypted memory: 2040K -[ 0.151148] Freeing unused kernel image (initmem) memory: 1408K -[ 0.156621] Write protecting the kernel read-only data: 14336k -[ 0.158657] Freeing unused kernel image (text/rodata gap) memory: 2044K -[ 0.159490] Freeing unused kernel image (rodata/data gap) memory: 188K -[ 0.160150] Run /init.sh as init process -462:C 15 May 2021 21:13:01.903 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo -462:C 15 May 2021 21:13:01.904 # Redis version=6.2.3, bits=64, commit=00000000, modified=0, pid=462, just started -462:C 15 May 2021 21:13:01.905 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf -462:M 15 May 2021 21:13:01.907 * Increased maximum number of open files to 10032 (it was originally set to 1024). -462:M 15 May 2021 21:13:01.909 * monotonic clock: POSIX clock_gettime - _._ - _.-``__ ''-._ - _.-`` `. `_. ''-._ Redis 6.2.3 (00000000/0) 64 bit - .-`` .-```. ```\/ _.,_ ''-._ - ( ' , .-` | `, ) Running in standalone mode - |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 - | `-._ `._ / _.-' | PID: 462 - `-._ `-._ `-./ _.-' _.-' - |`-._`-._ `-.__.-' _.-'_.-'| - | `-._`-._ _.-'_.-' | https://redis.io - `-._ `-._`-.__.-'_.-' _.-' - |`-._`-._ `-.__.-' _.-'_.-'| - | `-._`-._ _.-'_.-' | - `-._ `-._`-.__.-'_.-' _.-' - `-._ `-.__.-' _.-' - `-._ _.-' - `-.__.-' - -462:M 15 May 2021 21:13:01.922 # Server initialized -462:M 15 May 2021 21:13:01.923 * Ready to accept connections -#+end_src - -We can do a quick test with the following: -#+begin_src sh -; sudo docker run -it --rm redis redis-cli -h 192.168.128.9 -192.168.128.9:6379> get foo -(nil) -192.168.128.9:6379> set foo 1 -OK -192.168.128.9:6379> get foo -"1" -192.168.128.9:6379> -#+end_src diff --git a/users/fcuny/blog/content/notes/making-sense-intel-amd-cpus.org b/users/fcuny/blog/content/notes/making-sense-intel-amd-cpus.org deleted file mode 100644 index 60b433f..0000000 --- a/users/fcuny/blog/content/notes/making-sense-intel-amd-cpus.org +++ /dev/null @@ -1,131 +0,0 @@ -#+TITLE: Making sense of Intel and AMD CPUs naming -#+DATE: <2021-12-29 Wed> -#+TAGS[]: amd intel cpu -#+toc: headlines 1 - -* Intel -** Core -The line up for the core family is i3, i5, i7 and i9. As of December 2021, the current generation is Alder Lake (12th generation). - -The brand modifiers are: -- *i3*: laptops/low-end desktop -- *i5*: mainstream users -- *i7*: high-end users -- *i9*: enthusiast users - -How to read a SKU ? Let's use the [[https://ark.intel.com/content/www/us/en/ark/products/134594/intel-core-i712700k-processor-25m-cache-up-to-5-00-ghz.html][i7-12700K]] processor: -- *i7*: high end users -- *12*: 12th generation -- *700*: SKU digits, usually assigned in the order the processors are developed -- *K*: unlocked - -List of suffixes: -| suffix | meaning | -|--------+----------------------------------------| -| G.. | integrated graphics | -| E | embedded | -| F | require discrete graphic card | -| H | high performance for mobile | -| HK | high performance for mobile / unlocked | -| K | unlocked | -| S | special edition | -| T | power optimized lifestyle | -| U | mobile power efficient | -| Y | mobile low power | -| X/XE | unlocked, high end | - -#+begin_quote -*Unlocked,* what does that means ? -A processor with the *K* suffix is made with the an unlocked clock multiplier. When used with some specific chipset, it's possible to overclock the processor. -#+end_quote -*** Sockets/Chipsets -For the Alder Lake generation, the supported socket is the [[https://en.wikipedia.org/wiki/LGA_1700][LGA_1700]]. - -For now only supported chipset for Alder Lake are: -| feature | [[https://ark.intel.com/content/www/us/en/ark/products/218833/intel-z690-chipset.html][z690]] | [[https://www.intel.com/content/www/us/en/products/sku/218831/intel-h670-chipset/specifications.html][h670]] | [[https://ark.intel.com/content/www/us/en/ark/products/218832/intel-b660-chipset.html][b660]] | [[https://www.intel.com/content/www/us/en/products/sku/218829/intel-h610-chipset/specifications.html][h610]] | -|-----------------------------+----------+----------+---------+------| -| P and E cores over clocking | yes | no | no | no | -| memory over clocking | yes | yes | yes | no | -| DMI 4 lanes | 8 | 8 | 4 | 4 | -| chipset PCIe 4.0 lanes | up to 12 | up to 12 | up to 6 | none | -| chipset PCIe 3.0 lanes | up to 16 | up to 12 | up to 8 | 8 | -| SATA 3.0 ports | up to 8 | up to 8 | 4 | 4 | - -*** Alder Lake (12th generation) -| model | p-cores | e-cores | GHz (base) | GHz (boosted) | TDP | -|------------+---------+---------+------------+---------------+------| -| i9-12900K | 8 (16) | 8 | 3.2/2.4 | 5.1/3.9 | 241W | -| i9-12900KF | 8 (16) | 8 | 3.2/2.4 | 5.1/3.9 | 241W | -| i7-12700K | 8 (16) | 4 | 3.6/2.7 | 4.9/3.8 | 190W | -| i7-12700KF | 8 (16) | 4 | 3.6/2.7 | 4.9/3.8 | 190W | -| i5-12600K | 6 (12) | 4 | 3.7/2.8 | 4.9/3.6 | 150W | -| i5-12600KF | 6 (12) | 4 | 3.7/2.8 | 4.9/3.6 | 150W | - -- support DDR4 and DDR5 (up to DDR5-4800) -- support PCIe 4.0 and 5.0 (16 PCIe 5.0 and 4 PCIe 4.0) - -The socket used is the [[https://en.wikipedia.org/wiki/LGA_1700][LGA 1700]]. - -Alder lake is an hybrid architecture, featuring both P-cores (performance cores) and E-cores (efficient cores). P-cores are based on the [[https://en.wikipedia.org/wiki/Golden_Cove][Golden Cove]] architecture, while the E-cores are based on the [[https://en.wikipedia.org/wiki/Gracemont_(microarchitecture)][Gracemont]] architecture. - -This is a [[https://www.anandtech.com/show/16881/a-deep-dive-into-intels-alder-lake-microarchitectures/2][good article]] to read about this model. Inside the processor there's a microcontroller that monitors what each thread is doing. This can be used by the OS scheduler to hint on which core a thread should be scheduled on (between performance or efficiency). - -As of December 2021 this is not yet properly supported by the Linux kernel. -** Xeon -Xeon is the brand of Intel processor designed for non-consumer servers and workstations. -The most recent generations are: -- Skylake (2017) -- Cascade lake (2019) -- Cooper lake (2020) - -The following brand identifiers are used: -- platinium -- gold -- silver -- bronze -* AMD -** Ryzen -There are multiple generation for this brand of processors. They are based on the [[https://en.wikipedia.org/wiki/Zen_(microarchitecture)][zen micro architecture]]. The current (as of December 2021) generation is Ryzen 5000. - -The brand modifiers are: -- ryzen 3: entry level -- ryzen 5: mainstream -- ryzen 9: high end performance -- ryzen 9:enthusiast - -List of suffixes: -| suffix | meaning | -|--------+--------------------------------------------| -| X | high performance | -| G | integrated graphics | -| T | power optimized lifecycle | -| S | low power desktop with integrated graphics | -| H | high performance mobile | -| U | standard mobile | -| M | low power mobile | - -** EPYC -EPYC is the AMD brand of processors for the server market, based on the zen architecture. They use the [[https://en.wikipedia.org/wiki/Socket_SP3][SP3]] socket. The EPYC processor is chipset free. -** Threadripper -The threadripper is for high performance desktop. It uses the [[https://en.wikipedia.org/wiki/Socket_TR4][TR4]] socket. At the moment there's only one chipset that supports this process, the [[https://en.wikipedia.org/wiki/List_of_AMD_chipsets#TR4_chipsets][X399]]. - -The threadripper based on zen3 architecture is not yet released, but it's expected to hit the market in the first half of Q1 2022. -** Sockets/Chipsets -The majority of these processors use the [[https://en.wikipedia.org/wiki/Socket_AM4][AM4 socket]]. The threadripper line uses different sockets. - -There are multiple [[https://en.wikipedia.org/wiki/Socket_AM4#Chipsets][chipset]] for the AM4 socket. The more advanced ones are the B550 and the X570. - -The threadripper processors use the TR4, sTRX4 and sWRX8 sockets. -** Zen 3 -Zen 3 was released in November 2020. -| model | cores | GHz (base) | GHz (boosted) | PCIe lanes | TDP | -|---------------+---------+------------+---------------+------------+------| -| ryzen 5 5600x | 6 (12) | 3.7 | 4.6 | 24 | 65W | -| ryzen 7 5800 | 8 (16) | 3.4 | 4.6 | 24 | 65W | -| ryzen 7 5800x | 8 (16) | 3.8 | 4.7 | 24 | 105W | -| ryzen 9 5900 | 12 (24) | 3.0 | 4.7 | 24 | 65W | -| ryzen 9 5900x | 12 (24) | 3.7 | 4.8 | 24 | 105W | -| ryzen 9 5950x | 16 (32) | 3.4 | 4.9 | 24 | 105W | - -- support PCIe 3.0 and PCIe 4.0 (except for the G series) -- only support DDR4 (up to DDR4-3200) diff --git a/users/fcuny/blog/content/notes/stuff-about-pcie.org b/users/fcuny/blog/content/notes/stuff-about-pcie.org deleted file mode 100644 index 4d1a825..0000000 --- a/users/fcuny/blog/content/notes/stuff-about-pcie.org +++ /dev/null @@ -1,196 +0,0 @@ -#+TITLE: Stuff about PCIe -#+DATE: <2022-01-03 Mon> -#+TAGS[]: linux hardware -#+toc: t - -* Speed -The most common versions are 3 and 4, while 5 is starting to be available with newer Intel processors. - -| ver | encoding | transfer rate | x1 | x2 | x4 | x8 | x16 | -|-----+-----------+---------------+------------+-------------+------------+------------+-------------| -| 1 | 8b/10b | 2.5GT/s | 250MB/s | 500MB/s | 1GB/s | 2GB/s | 4GB/s | -| 2 | 8b/10b | 5.0GT/s | 500MB/s | 1GB/s | 2GB/s | 4GB/s | 8GB/s | -| 3 | 128b/130b | 8.0GT/s | 984.6 MB/s | 1.969 GB/s | 3.94 GB/s | 7.88 GB/s | 15.75 GB/s | -| 4 | 128b/130b | 16.0GT/s | 1969 MB/s | 3.938 GB/s | 7.88 GB/s | 15.75 GB/s | 31.51 GB/s | -| 5 | 128b/130b | 32.0GT/s | 3938 MB/s | 7.877 GB/s | 15.75 GB/s | 31.51 GB/s | 63.02 GB/s | -| 6 | 128b/130 | 64.0 GT/s | 7877 MB/s | 15.754 GB/s | 31.51 GB/s | 63.02 GB/s | 126.03 GB/s | - -This is a [[https://community.mellanox.com/s/article/understanding-pcie-configuration-for-maximum-performance][useful]] link to understand the formula: Maximum PCIe Bandwidth = *SPEED* * *WIDTH* * (1 - ENCODING) - 1Gb/s. - -We remove 1Gb/s for protocol overhead and error corrections. The main difference between the generations besides the supported speed is the encoding overhead of the packet. For generations 1 and 2, each packet sent on the PCIe has 20% PCIe headers overhead. This was improved in generation 3, where the overhead was reduced to 1.5% (2/130) - see [[https://en.wikipedia.org/wiki/8b/10b_encoding][8b/10b encoding]] and [[https://en.wikipedia.org/wiki/64b/66b_encoding][128b/130b encoding]]. - -If we apply the formula, for a PCIe version 3 device we can expect 3.7GB/s of data transfer rate: -#+begin_src -8GT/s * 4 lanes * (1 - 2/130) - 1G = 32G * 0.985 - 1G = ~30Gb/s -> 3750MB/s -#+end_src -* Topology -The easiest way to see the PCIe topology is with =lspci=: -#+begin_src -$ lspci -tv --[0000:00]-+-00.0 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Root Complex - +-01.0 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge - +-01.1-[01]----00.0 OCZ Technology Group, Inc. RD400/400A SSD - +-01.3-[02-03]----00.0-[03]----00.0 ASPEED Technology, Inc. ASPEED Graphics Family - +-01.5-[04]--+-00.0 Intel Corporation I350 Gigabit Network Connection - | +-00.1 Intel Corporation I350 Gigabit Network Connection - | +-00.2 Intel Corporation I350 Gigabit Network Connection - | \-00.3 Intel Corporation I350 Gigabit Network Connection - +-02.0 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge - +-03.0 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge - +-04.0 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge - +-07.0 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge - +-07.1-[05]--+-00.0 Advanced Micro Devices, Inc. [AMD] Zeppelin/Raven/Raven2 PCIe Dummy Function - | +-00.2 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Platform Security Processor - | \-00.3 Advanced Micro Devices, Inc. [AMD] Zeppelin USB 3.0 Host controller - +-08.0 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge - +-08.1-[06]--+-00.0 Advanced Micro Devices, Inc. [AMD] Zeppelin/Renoir PCIe Dummy Function - | +-00.1 Advanced Micro Devices, Inc. [AMD] Zeppelin Cryptographic Coprocessor NTBCCP - | +-00.2 Advanced Micro Devices, Inc. [AMD] FCH SATA Controller [AHCI mode] - | \-00.3 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) HD Audio Controller - +-14.0 Advanced Micro Devices, Inc. [AMD] FCH SMBus Controller - +-14.3 Advanced Micro Devices, Inc. [AMD] FCH LPC Bridge - +-18.0 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 0 - +-18.1 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 1 - +-18.2 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 2 - +-18.3 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 3 - +-18.4 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 4 - +-18.5 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 5 - +-18.6 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 6 - \-18.7 Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) Data Fabric: Device 18h; Function 7 -#+end_src -* View a single device -#+begin_src -$ lspci -s 0000:01:00.0 -01:00.0 Non-Volatile memory controller: OCZ Technology Group, Inc. RD400/400A SSD (rev 01) -#+end_src -* Reading =lspci= output -#+begin_src -$ sudo lspci -vvv -s 0000:01:00.0 -01:00.0 Non-Volatile memory controller: OCZ Technology Group, Inc. RD400/400A SSD (rev 01) (prog-if 02 [NVM Express]) - Subsystem: OCZ Technology Group, Inc. RD400/400A SSD - Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ - Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- SERR- -#+TAGS[]: go emacs -#+toc: t - -/This document assumes go version >= 1.16/. - -* Go Modules -[[https://blog.golang.org/using-go-modules][Go modules]] have been added in 2019 with Go 1.11. A number of changes were introduced with [[https://blog.golang.org/go116-module-changes][Go 1.16]]. This document is a reference for me so that I can find answers to things I keep forgetting. -** Creating a new module -To create a new module, run =go mod init golang.fcuny.net/m=. This will create two files: =go.mod= and =go.sum=. - -In the =go.mod= file you'll find: -- the module import path (prefixed with =module=) -- the list of dependencies (within =require=) -- the version of go to use for the module -** Versioning -To bump the version of a module: -#+begin_src sh -$ git tag v1.2.3 -$ git push --tags -#+end_src - -Then as a user: -#+begin_src sh -$ go get -d golang.fcuny.net/m@v1.2.3 -#+end_src -** Updating dependencies -To update the dependencies, run =go mod tidy= -** Editing a module -If you need to modify a module, you can check out the module in your workspace (=git clone =). - -Edit the =go.mod= file to add -#+begin_src go -replace => -#+end_src - -Then modify the code of the module and the next time you compile the project, the cloned module will be used. - -This is particularly useful when trying to debug an issue with an external module. -** Vendor-ing modules -It's still possible to vendor modules by running =go mod vendor=. This can be useful in the case of a CI setup that does not have access to internet. -** Proxy -As of version 1.13, the variable =GOPROXY= defaults to =https://proxy.golang.org,direct= (see [[https://github.com/golang/go/blob/c95464f0ea3f87232b1f3937d1b37da6f335f336/src/cmd/go/internal/cfg/cfg.go#L269][here]]). As a result, when running something like =go get golang.org/x/tools/gopls@latest=, the request goes through the proxy. - -There's a number of ways to control the behavior, they are documented [[https://golang.org/ref/mod#private-modules][here]]. - -There's a few interesting things that can be done when using the proxy. There's a few special URLs (better documentation [[https://golang.org/ref/mod#goproxy-protocol][here]]): -| path | description | -|-----------------------+------------------------------------------------------------------------------------------| -| $mod/@v/list | Returns the list of known versions - there's one version per line and it's in plain text | -| $mod/@v/$version.info | Returns metadata about a version in JSON format | -| $mod/@v/$version.mod | Returns the =go.mod= file for that version | - -For example, looking at the most recent versions for =gopls=: -#+begin_src sh -; curl -s -L https://proxy.golang.org/golang.org/x/tools/gopls/@v/list|sort -r|head -v0.7.1-pre.2 -v0.7.1-pre.1 -v0.7.1 -v0.7.0-pre.3 -v0.7.0-pre.2 -v0.7.0-pre.1 -v0.7.0 -v0.6.9-pre.1 -v0.6.9 -v0.6.8-pre.1 -#+end_src - -Let's check the details for the most recent version -#+begin_src sh -; curl -s -L https://proxy.golang.org/golang.org/x/tools/gopls/@v/list|sort -r|head -v0.7.1-pre.2 -v0.7.1-pre.1 -v0.7.1 -v0.7.0-pre.3 -v0.7.0-pre.2 -v0.7.0-pre.1 -v0.7.0 -v0.6.9-pre.1 -v0.6.9 -v0.6.8-pre.1 -#+end_src - -And let's look at the content of the =go.mod= for that version too: -#+begin_src sh -; curl -s -L https://proxy.golang.org/golang.org/x/tools/gopls/@v/v0.7.1-pre.2.mod -module golang.org/x/tools/gopls - -go 1.17 - -require ( - github.com/BurntSushi/toml v0.3.1 // indirect - github.com/google/go-cmp v0.5.5 - github.com/google/safehtml v0.0.2 // indirect - github.com/jba/templatecheck v0.6.0 - github.com/sanity-io/litter v1.5.0 - github.com/sergi/go-diff v1.1.0 - golang.org/x/mod v0.4.2 - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - golang.org/x/sys v0.0.0-20210510120138-977fb7262007 - golang.org/x/text v0.3.6 // indirect - golang.org/x/tools v0.1.6-0.20210802203754-9b21a8868e16 - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect - honnef.co/go/tools v0.2.0 - mvdan.cc/gofumpt v0.1.1 - mvdan.cc/xurls/v2 v2.2.0 -) -#+end_src -* Tooling -** LSP -=gopls= is the default implementation of the language server protocol maintained by the Go team. To install the latest version, run =go install golang.org/x/tools/gopls@latest= -** =staticcheck= -[[https://staticcheck.io/][=staticcheck=]] is a great tool to run against your code to find issues. To install the latest version, run =go install honnef.co/go/tools/cmd/staticcheck@latest=. -* Emacs integration -** =go-mode= -[[https://github.com/dominikh/go-mode.el][This is the mode]] to install to get syntax highlighting (mostly). -** Integration with LSP -Emacs has a pretty good integration with LSP. -https://geeksocket.in/posts/emacs-lsp-go/ -*** =lsp-mode= -[[src:https://github.com/emacs-lsp/lsp-mode][This is the main mode to install]]. It provides the integration with LSP. - -I've configured the mode like this: -#+begin_src elisp -(use-package lsp-mode - :ensure t - :commands (lsp lsp-deferred) - :diminish lsp-mode - :hook ((go-mode . lsp-deferred) - (lsp-mode . (lambda() (let ((lsp-keymap-prefix "C-c l")) - (lsp-enable-which-key-integration))))) - :config - (define-key lsp-mode-map (kbd "C-c l") lsp-command-map) - (lsp-register-custom-settings - '(("gopls.completeUnimported" t t) - ("gopls.staticcheck" t t))) - :bind - (("C-c l i" . lsp-ui-imenu)) - :custom - (lsp-session-file (expand-file-name "lsp-session-v1" fcuny/path-emacs-var)) - (lsp-enable-snippet nil) - (lsp-signature-doc-lines 5) - (lsp-modeline-diagnostic-scope :workspace) - (lsp-completion-provider :capf) - (lsp-completion-enable t) - (lsp-enable-indentation t) - (lsp-eldoc-render-all t) - (lsp-prefer-flymake nil)) -#+end_src - -+ =C-c l= brings a menu via [[https://github.com/abo-abo/hydra][hydra]] -+ By default it seems that =staticcheck= is not used, so I force it with the =lsp-register-custom-settings= -+ I prefer [[https://www.flycheck.org/en/latest/][flycheck]] -*** =lsp-ui= -This is mostly for UI tweaks. I use the following configuration -#+begin_src elisp -(use-package lsp-ui - :ensure t - :hook (lsp-mode . lsp-ui-mode) - :commands lsp-ui-mode - :custom - (lsp-ui-doc-delay 0.4) - (lsp-ui-doc-enable t) - (lsp-ui-doc-position 'top) - (lsp-ui-doc-include-signature t) - (lsp-ui-peek-enable t) - (lsp-ui-sideline-enable t) - (lsp-ui-imenu-enable t) - (lsp-ui-flycheck-enable t)) - -#+end_src -*** =lsp-ivy= -I use ivy for completion, [[https://github.com/emacs-lsp/lsp-ivy][it provides]] completion based on the current workspace. This is my configuration: -#+begin_src elisp -(use-package lsp-ivy - :ensure t - :commands lsp-ivy-workspace-symbol) -#+end_src -*** =lsp-treemacs= -[[https://github.com/emacs-lsp/lsp-treemacs][It provides]] some nice improvement regarding the UI. This is my configuration: -#+begin_src elisp -(use-package lsp-treemacs - :ensure t - :config - (lsp-treemacs-sync-mode 1)) - -#+end_src -* Profiling -** pprof -[[https://github.com/google/pprof][pprof]] is a tool to visualize performance data. Let's start with the following test: -#+begin_src go -package main - -import ( - "strings" - "testing" -) - -func BenchmarkStringJoin(b *testing.B) { - input := []string{"a", "b"} - for i := 0; i <= b.N; i++ { - r := strings.Join(input, " ") - if r != "a b" { - b.Errorf("want a b got %s", r) - } - } -} -#+end_src - -Let's run a benchmark with ~go test . -bench=. -cpuprofile cpu_profile.out~: -#+begin_src go -goos: linux -goarch: amd64 -pkg: golang.fcuny.net/m -cpu: Intel(R) Core(TM) i3-1005G1 CPU @ 1.20GHz -BenchmarkStringJoin-4 41833486 26.85 ns/op 3 B/op 1 allocs/op -PASS -ok golang.fcuny.net/m 1.327s -#+end_src - -And let's take a look at the profile with =go tool pprof cpu_profile.out= -#+begin_src sh -File: m.test -Type: cpu -Time: Aug 15, 2021 at 3:01pm (PDT) -Duration: 1.31s, Total samples = 1.17s (89.61%) -Entering interactive mode (type "help" for commands, "o" for options) -(pprof) top -Showing nodes accounting for 1100ms, 94.02% of 1170ms total -Showing top 10 nodes out of 41 - flat flat% sum% cum cum% - 240ms 20.51% 20.51% 240ms 20.51% runtime.memmove - 220ms 18.80% 39.32% 320ms 27.35% runtime.mallocgc - 130ms 11.11% 50.43% 450ms 38.46% runtime.makeslice - 110ms 9.40% 59.83% 1150ms 98.29% golang.fcuny.net/m.BenchmarkStringJoin - 110ms 9.40% 69.23% 580ms 49.57% strings.(*Builder).grow (inline) - 110ms 9.40% 78.63% 1040ms 88.89% strings.Join - 70ms 5.98% 84.62% 300ms 25.64% strings.(*Builder).WriteString - 50ms 4.27% 88.89% 630ms 53.85% strings.(*Builder).Grow (inline) - 40ms 3.42% 92.31% 40ms 3.42% runtime.nextFreeFast (inline) - 20ms 1.71% 94.02% 20ms 1.71% runtime.getMCache (inline) -#+end_src - -We can get a breakdown of the data for our module: -#+begin_src sh -(pprof) list golang.fcuny.net -Total: 1.17s -ROUTINE ======================== golang.fcuny.net/m.BenchmarkStringJoin in /home/fcuny/workspace/gobench/app_test.go - 110ms 1.15s (flat, cum) 98.29% of Total - . . 5: "testing" - . . 6:) - . . 7: - . . 8:func BenchmarkStringJoin(b *testing.B) { - . . 9: b.ReportAllocs() - 10ms 10ms 10: input := []string{"a", "b"} - . . 11: for i := 0; i <= b.N; i++ { - 20ms 1.06s 12: r := strings.Join(input, " ") - 80ms 80ms 13: if r != "a b" { - . . 14: b.Errorf("want a b got %s", r) - . . 15: } - . . 16: } - . . 17:} -#+end_src -- cgit 1.4.1 From cd6494898260b08f76dc5f5934f952a5219779ef Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 1 May 2022 13:38:03 -0700 Subject: scripts: actually deploy to fly --- users/fcuny/blog/scripts/deploy.sh | 2 ++ 1 file changed, 2 insertions(+) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/scripts/deploy.sh b/users/fcuny/blog/scripts/deploy.sh index 82919c6..ede848c 100755 --- a/users/fcuny/blog/scripts/deploy.sh +++ b/users/fcuny/blog/scripts/deploy.sh @@ -3,6 +3,8 @@ git diff --exit-code git diff --staged --exit-code +flyctl deploy + VERSION=$(flyctl info -j |jq -r '.App | "fcuny.net/v\(.Version)"') git tag -a --message ${VERSION} ${VERSION} -- cgit 1.4.1 From ded2438ad50d819d8d438c405a9a93ef34880001 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 1 May 2022 13:40:31 -0700 Subject: config: remove the link to the feed It's already in the footer. --- users/fcuny/blog/config.toml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/config.toml b/users/fcuny/blog/config.toml index c47b946..8cb0c62 100644 --- a/users/fcuny/blog/config.toml +++ b/users/fcuny/blog/config.toml @@ -5,7 +5,7 @@ publishDir = "docs" enableGitInfo = true [params] - homeText = "A collection of notes" + homeText = "A collection of posts" [author] name = "Franck Cuny" @@ -16,16 +16,9 @@ enableGitInfo = true [permalinks] blog = "/blog/:slug/" - notes = "/notes/:slug/" tags = "/tags/:slug/" [menu] - [[menu.main]] - identifier = "RSS" - name = "RSS" - title = "~/blog/feed" - url = "/feed.xml" - weight = 130 [markup] [markup.highlight] -- cgit 1.4.1 From 48494b64c7fd9a35fb6618948685e0221e59a567 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 1 May 2022 13:42:43 -0700 Subject: static: add my resume as a static page --- users/fcuny/blog/static/resume.html | 209 ++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 users/fcuny/blog/static/resume.html (limited to 'users/fcuny') diff --git a/users/fcuny/blog/static/resume.html b/users/fcuny/blog/static/resume.html new file mode 100644 index 0000000..0f1cd83 --- /dev/null +++ b/users/fcuny/blog/static/resume.html @@ -0,0 +1,209 @@ + + + + + + + + Franck Cuny + + + + + +
    +

    Franck Cuny

    +

    franck@fcuny.net

    +
    +

    I'm a seasoned Site Reliability Engineer with experience in large +scale distributed systems. I'm invested in mentoring junior and senior +engineers to help them increase their impact. I'm always looking to +learn from those around me.

    +

    Specializations: distributed systems, +containerization, debugging, software development, reliability.

    +

    Experience

    +

    Roblox, San Mateo

    + + + + + + + + + +
    Site Reliability EngineerPrincipal (IC6)SRE GroupFeb 2022 - to date
    +

    I'm the Team Lead for the Site Reliability group that was started at +the end of 2021.

    +

    I'm defining the road-map and identify areas where SREs can partner +with different team to improve overall reliability of our services.

    +

    Twitter, San Francisco

    +

    Compute

    + + + + + + + + + + + + + + + +
    Software EngineerSenior StaffCompute InfoAug 2021 - Jan 2022
    Site Reliability EngineerSenior StaffCompute SREsJan 2018 - Aug 2021
    +

    Initially the Tech Lead of a team of 6 SREs supporting the Compute +infrastructure. In August 2021 I changed to be a Software Engineer and +was leading one of the effort to adopt Kubernetes for our on-premise +infrastructure. As a Tech Lead I helped define number of internal +processes for the team, from on-call rotations to postmortem +processes.

    +

    Twitter's Compute is one of the largest Mesos cluster in the world +(XXX thousands of nodes across multiple data centers). The team defined +KPIs, improved automation to mange the large fleet of bare metal +machines, defined APIs for maintenance with partner teams.

    +

    In addition to supporting Aurora/Mesos, I also lead a number of +effort related to Kubernetes, both on-premise and in the cloud.

    +

    Finally, I've helped Twitter save XX of millions of dollar in +hardware by designing and implementing strategies to significantly +improve the hardware utilization of our bare metal infrastructure.

    +

    Storage

    + + + + + + + + + +
    Site Reliability EngineerStaffStorage SREsAug 2014 - Jan 2018
    +

    For 4 years I supported the Messaging and Manhattan teams. I moved +all the pub-sub systems from bare-metal deployment to Aurora/Mesos, +being the first storage team to adopt the Compute orchestration +platform. This helped reducing operations, time to deploy, and improve +overall reliability. I pushed for adopting 10Gb+ networking in our data +center to help our team to scale. I was the SRE Tech Lead for the +Manhattan team, helping with performance, operation and automation.

    +

    Senior +Software Engineer - Say Media, San Francisco

    + + + + + + + + + +
    Software EngineerSenior SWEInfrastructureAug 2011 - Aug 2014
    +

    During my time at Say Media, I worked on two different teams. I +started as a software engineer in the platform team building the various +APIs; I then transitioned to the operation team, to develop tooling to +increase the effectiveness of the engineering organization.

    +

    Senior Software +Engineer - Linkfluence, Paris

    + + + + + + + + + +
    Software EngineerSenior SWEInfrastructureJuly 2007 - July 2011
    +

    I was one of the early engineers joining Linkfluence in 2007. I led +the development of the company's crawler (web, feeds). I was responsible +for defining the early architecture of the company, and designed the +internal platforms (Service Oriented Architecture). I helped the company +to contribute to open source projects; contributed to open source +projects on behalf of the company; represented the company at numerous +open sources conferences in Europe.

    +

    Technical Skills

    +
      +
    • Languages Python, Go, Ruby, Perl
    • +
    • Frameworks Kubernetes, Aurora, Mesos
    • +
    • Databases RDBMS, NOSql
    • +
    • Dev tools Git
    • +
    + + -- cgit 1.4.1 From 2e8a5c27fb3c48cd4c32e001d4cfc4b3f051d72f Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 10 May 2022 17:56:40 -0700 Subject: add drone configuration and cleanup nix Add a drone configuration to run the deploy on a push to the main branch. Cleanup the nix configuration to only keep support for `nix run` (which will run the hugo server). --- users/fcuny/blog/.drone.yml | 18 ++++++++++++++++++ users/fcuny/blog/.gitignore | 2 ++ users/fcuny/blog/flake.lock | 16 ++++++++++++++++ users/fcuny/blog/flake.nix | 32 ++++++++++++++++++-------------- 4 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 users/fcuny/blog/.drone.yml (limited to 'users/fcuny') diff --git a/users/fcuny/blog/.drone.yml b/users/fcuny/blog/.drone.yml new file mode 100644 index 0000000..7c0c283 --- /dev/null +++ b/users/fcuny/blog/.drone.yml @@ -0,0 +1,18 @@ +kind: pipeline +type: exec +name: default + +trigger: + event: + - push + branch: + - master + +steps: + - name: deploy + environment: + FLY_API_TOKEN: + from_secret: FLY_API_TOKEN + commands: + - nix develop + - ./script/deploy.sh diff --git a/users/fcuny/blog/.gitignore b/users/fcuny/blog/.gitignore index 6e68499..8ec0a90 100644 --- a/users/fcuny/blog/.gitignore +++ b/users/fcuny/blog/.gitignore @@ -1 +1,3 @@ /docs/ +/.hugo_build.lock +/result diff --git a/users/fcuny/blog/flake.lock b/users/fcuny/blog/flake.lock index d7426e1..8af4281 100644 --- a/users/fcuny/blog/flake.lock +++ b/users/fcuny/blog/flake.lock @@ -1,5 +1,20 @@ { "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1649676176, + "narHash": "sha256-OWKJratjt2RW151VUlJPRALb7OU2S5s+f0vLj4o1bHM=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "a4b154ebbdc88c8498a5c7b01589addc9e9cb678", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1651345462, @@ -17,6 +32,7 @@ }, "root": { "inputs": { + "flake-utils": "flake-utils", "nixpkgs": "nixpkgs" } } diff --git a/users/fcuny/blog/flake.nix b/users/fcuny/blog/flake.nix index 59ef578..fa39b45 100644 --- a/users/fcuny/blog/flake.nix +++ b/users/fcuny/blog/flake.nix @@ -1,19 +1,23 @@ { description = "Franck Cuny's personal website."; - inputs = { nixpkgs.url = "github:nixos/nixpkgs"; }; + inputs = { + nixpkgs.url = "github:nixos/nixpkgs"; + flake-utils.url = "github:numtide/flake-utils"; + }; - outputs = { self, nixpkgs }: - let pkgs = nixpkgs.legacyPackages.x86_64-linux; - in { - defaultApp.x86_64-linux = self.apps.server; - apps.server = pkgs.writers.writeBashBin "server" '' - set -e - set -o pipefail - PATH=${pkgs.lib.makeBinPath [ pkgs.hugo pkgs.git ]} - hugo server - ''; - devShell.x86_64-linux = - pkgs.mkShell { buildInputs = with pkgs; [ hugo flyctl git ]; }; - }; + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let pkgs = nixpkgs.legacyPackages.${system}; + in { + defaultApp = pkgs.writers.writeBashBin "run-hugo" '' + set -e + set -o pipefail + export PATH=${pkgs.lib.makeBinPath [ pkgs.hugo pkgs.git ]} + hugo server -D + ''; + + devShell = + pkgs.mkShell { buildInputs = with pkgs; [ hugo flyctl git ]; }; + }); } -- cgit 1.4.1 From 3215fa89fbaff54a9b2e4e3d31afddb1d15076f6 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 10 May 2022 18:01:01 -0700 Subject: add a basic README --- users/fcuny/blog/README.org | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 users/fcuny/blog/README.org (limited to 'users/fcuny') diff --git a/users/fcuny/blog/README.org b/users/fcuny/blog/README.org new file mode 100644 index 0000000..0158727 --- /dev/null +++ b/users/fcuny/blog/README.org @@ -0,0 +1,8 @@ +#+TITLE: fcuny.net + +My personal blog. + +* Run +The dependencies are managed with nix. Running =nix run= will start the hugo server. +* Deploy +You can deploy the site by running [[file:scripts/deploy.sh][scripts/deploy.sh]]. There's also a [[file:.drone.yml][.drone.yml]] configuration to trigger a build and deploy with drone. -- cgit 1.4.1 From 18dc67d95131bdba722b35ff317d19f23781d4b8 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 10 May 2022 18:02:07 -0700 Subject: fix name of the branch for done Delete the workflow for GitHub actions. --- users/fcuny/blog/.drone.yml | 2 +- users/fcuny/blog/.github/workflows/gh-pages.yml | 18 ------------------ 2 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 users/fcuny/blog/.github/workflows/gh-pages.yml (limited to 'users/fcuny') diff --git a/users/fcuny/blog/.drone.yml b/users/fcuny/blog/.drone.yml index 7c0c283..84b4833 100644 --- a/users/fcuny/blog/.drone.yml +++ b/users/fcuny/blog/.drone.yml @@ -6,7 +6,7 @@ trigger: event: - push branch: - - master + - main steps: - name: deploy diff --git a/users/fcuny/blog/.github/workflows/gh-pages.yml b/users/fcuny/blog/.github/workflows/gh-pages.yml deleted file mode 100644 index bf3398a..0000000 --- a/users/fcuny/blog/.github/workflows/gh-pages.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: github pages - -on: - push: - branches: - - main # Set a branch to deploy - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Setup Hugo - uses: superfly/flyctl-actions@master - env: - FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} - with: - args: "deploy" -- cgit 1.4.1 From 325bed1c113d8688563689402abd974c77cd0cb4 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 10 May 2022 18:03:18 -0700 Subject: I'll get it right at some point --- users/fcuny/blog/.drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/.drone.yml b/users/fcuny/blog/.drone.yml index 84b4833..1006ab4 100644 --- a/users/fcuny/blog/.drone.yml +++ b/users/fcuny/blog/.drone.yml @@ -15,4 +15,4 @@ steps: from_secret: FLY_API_TOKEN commands: - nix develop - - ./script/deploy.sh + - ./scripts/deploy.sh -- cgit 1.4.1 From 381895c23715e00f1c441cb54bf66ca714b4c0f6 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 10 May 2022 18:04:19 -0700 Subject: maybe this time --- users/fcuny/blog/.drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/.drone.yml b/users/fcuny/blog/.drone.yml index 1006ab4..83fbc12 100644 --- a/users/fcuny/blog/.drone.yml +++ b/users/fcuny/blog/.drone.yml @@ -15,4 +15,4 @@ steps: from_secret: FLY_API_TOKEN commands: - nix develop - - ./scripts/deploy.sh + - bash ./scripts/deploy.sh -- cgit 1.4.1 From 9c1943defe0eb37ccebd4c7756d8f4c0c021d208 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 10 May 2022 18:05:53 -0700 Subject: one more time --- users/fcuny/blog/.drone.yml | 3 +-- users/fcuny/blog/flake.nix | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/.drone.yml b/users/fcuny/blog/.drone.yml index 83fbc12..67bf620 100644 --- a/users/fcuny/blog/.drone.yml +++ b/users/fcuny/blog/.drone.yml @@ -14,5 +14,4 @@ steps: FLY_API_TOKEN: from_secret: FLY_API_TOKEN commands: - - nix develop - - bash ./scripts/deploy.sh + - nix shell --command bash ./scripts/deploy.sh diff --git a/users/fcuny/blog/flake.nix b/users/fcuny/blog/flake.nix index fa39b45..35ada07 100644 --- a/users/fcuny/blog/flake.nix +++ b/users/fcuny/blog/flake.nix @@ -18,6 +18,6 @@ ''; devShell = - pkgs.mkShell { buildInputs = with pkgs; [ hugo flyctl git ]; }; + pkgs.mkShell { buildInputs = with pkgs; [ hugo flyctl git jq ]; }; }); } -- cgit 1.4.1 From 3f98841adfb8b553678025219caa45625b396ddf Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 10 May 2022 19:18:21 -0700 Subject: another try --- users/fcuny/blog/flake.nix | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/flake.nix b/users/fcuny/blog/flake.nix index 35ada07..7d5a4b2 100644 --- a/users/fcuny/blog/flake.nix +++ b/users/fcuny/blog/flake.nix @@ -10,6 +10,18 @@ flake-utils.lib.eachDefaultSystem (system: let pkgs = nixpkgs.legacyPackages.${system}; in { + defaultPackage = with pkgs; + stdenv.mkDerivation { + pname = "fcuny.net"; + version = self.lastModifiedDate; + src = ./.; + buildInputs = [ hugo git ]; + buildPhase = '' + mkdir -p $out + hugo --minify --destination $out + ''; + dontInstall = true; + }; defaultApp = pkgs.writers.writeBashBin "run-hugo" '' set -e set -o pipefail @@ -17,6 +29,15 @@ hugo server -D ''; + deploy = pkgs.writers.writeBashBin "run-deploy" '' + set -e + set -o pipefile + export PATH=${ + pkgs.lib.makeBinPath [ pkgs.hugo pkgs.git pkgs.jq pkgs.flyctl ] + } + ./scripts/deploy.sh + ''; + devShell = pkgs.mkShell { buildInputs = with pkgs; [ hugo flyctl git jq ]; }; }); -- cgit 1.4.1 From d2e2cc7fcad35cbb3189d1f51bf01bed57e7beaa Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 10 May 2022 19:28:33 -0700 Subject: i don't think it will work --- users/fcuny/blog/.drone.yml | 2 +- users/fcuny/blog/flake.nix | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/.drone.yml b/users/fcuny/blog/.drone.yml index 67bf620..0031ad9 100644 --- a/users/fcuny/blog/.drone.yml +++ b/users/fcuny/blog/.drone.yml @@ -14,4 +14,4 @@ steps: FLY_API_TOKEN: from_secret: FLY_API_TOKEN commands: - - nix shell --command bash ./scripts/deploy.sh + - nix run .#deploy diff --git a/users/fcuny/blog/flake.nix b/users/fcuny/blog/flake.nix index 7d5a4b2..1c9b9dd 100644 --- a/users/fcuny/blog/flake.nix +++ b/users/fcuny/blog/flake.nix @@ -22,6 +22,7 @@ ''; dontInstall = true; }; + defaultApp = pkgs.writers.writeBashBin "run-hugo" '' set -e set -o pipefail @@ -29,14 +30,15 @@ hugo server -D ''; - deploy = pkgs.writers.writeBashBin "run-deploy" '' - set -e - set -o pipefile - export PATH=${ - pkgs.lib.makeBinPath [ pkgs.hugo pkgs.git pkgs.jq pkgs.flyctl ] - } - ./scripts/deploy.sh - ''; + apps = { + deploy = pkgs.pkgs.writeShellScriptBin "run-deploy" '' + set -euxo pipefail + export PATH=${ + pkgs.lib.makeBinPath [ pkgs.hugo pkgs.git pkgs.jq pkgs.flyctl ] + }:$PATH + ./scripts/deploy.sh + ''; + }; devShell = pkgs.mkShell { buildInputs = with pkgs; [ hugo flyctl git jq ]; }; -- cgit 1.4.1 From 573db8f7db0c489b3a2f7c514f8a0651a7b26439 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 10 May 2022 19:29:19 -0700 Subject: who knows --- users/fcuny/blog/flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/flake.nix b/users/fcuny/blog/flake.nix index 1c9b9dd..79e6953 100644 --- a/users/fcuny/blog/flake.nix +++ b/users/fcuny/blog/flake.nix @@ -36,7 +36,7 @@ export PATH=${ pkgs.lib.makeBinPath [ pkgs.hugo pkgs.git pkgs.jq pkgs.flyctl ] }:$PATH - ./scripts/deploy.sh + bash ./scripts/deploy.sh ''; }; -- cgit 1.4.1 From b5f9075e0a2a695c744a4684fdb360cfa227c1b2 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 10 May 2022 19:37:45 -0700 Subject: delete Makefile This is not needed anymore, I'm not running it in a container, and the build is done remotely by fly when I do a build. --- users/fcuny/blog/Makefile | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 users/fcuny/blog/Makefile (limited to 'users/fcuny') diff --git a/users/fcuny/blog/Makefile b/users/fcuny/blog/Makefile deleted file mode 100644 index e2731d4..0000000 --- a/users/fcuny/blog/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -DOCKER := DOCKER_BUILDKIT=1 docker -DOCKER_BUILD_ARGS := -DOCKER_IMAGE := fcuny/fcuny.net -DOCKER_IMAGE_REF := $(shell git rev-parse HEAD) -DOCKERFILE := Dockerfile -PROJECT_DIR := $(realpath $(CURDIR)) - -.PHONY: docker-build docker-run - -docker-build: - @echo "Building Docker image ..." - $(DOCKER) build $(DOCKER_BUILD_ARGS) \ - --tag "${DOCKER_IMAGE}:${DOCKER_IMAGE_REF}" \ - --file "$(DOCKERFILE)" \ - "$(PROJECT_DIR)" - -docker-run: docker-build - @echo "Running Docker image ..." - $(DOCKER) run -ti --rm -p 8080:8080 "${DOCKER_IMAGE}:${DOCKER_IMAGE_REF}" -- cgit 1.4.1 From afaa1136373f4070d4621257f4fa981356509370 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Tue, 10 May 2022 19:42:11 -0700 Subject: deploy: stop the flyctl agent at the end I ran into the following issue: ``` The agent failed to start with the following error log: 162022/05/11 02:38:11.375368 srv another instance of the agent is already running ``` I'm not sure this is the right approach, but it's a start. --- users/fcuny/blog/scripts/deploy.sh | 2 ++ 1 file changed, 2 insertions(+) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/scripts/deploy.sh b/users/fcuny/blog/scripts/deploy.sh index ede848c..69ad82a 100755 --- a/users/fcuny/blog/scripts/deploy.sh +++ b/users/fcuny/blog/scripts/deploy.sh @@ -10,3 +10,5 @@ VERSION=$(flyctl info -j |jq -r '.App | "fcuny.net/v\(.Version)"') git tag -a --message ${VERSION} ${VERSION} git push origin --all git push origin --tags + +flyctl agent stop -- cgit 1.4.1 From 4bd39b94f4a67d7d829e617ae69bb12a3faf83f5 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Wed, 11 May 2022 08:19:43 -0700 Subject: sign the drone configuration --- users/fcuny/blog/.drone.yml | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'users/fcuny') diff --git a/users/fcuny/blog/.drone.yml b/users/fcuny/blog/.drone.yml index 0031ad9..e312fb4 100644 --- a/users/fcuny/blog/.drone.yml +++ b/users/fcuny/blog/.drone.yml @@ -1,3 +1,4 @@ +--- kind: pipeline type: exec name: default @@ -15,3 +16,8 @@ steps: from_secret: FLY_API_TOKEN commands: - nix run .#deploy +--- +kind: signature +hmac: 2fbe0f7be54296d1d2aa91d096b1a4e31cfa15104b2284fea15f0865e7cb3545 + +... -- cgit 1.4.1