Migrated T.I.L. posts to blog
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
This commit is contained in:
parent
080912401b
commit
652cee0e2e
57
src/posts/2020-09-13-tekton-multi-arch-builds.md
Normal file
57
src/posts/2020-09-13-tekton-multi-arch-builds.md
Normal file
@ -0,0 +1,57 @@
|
||||
---
|
||||
layout: post.html
|
||||
title: "T.I.L. Tekton Multi-Arch Image Builds"
|
||||
summary: "Today I Learnt: Tekton Multi-Arch Image Builds"
|
||||
date: 2020-09-13T01:49:37+01:00
|
||||
tags: til tekton docker
|
||||
|
||||
---
|
||||
|
||||
Using Buildkit to build multi-arch compatible images without Docker daemon:
|
||||
|
||||
```yaml
|
||||
apiVersion: tekton.dev/v1beta1
|
||||
kind: Task
|
||||
metadata:
|
||||
name: docker-build-and-publish
|
||||
namespace: tekton-pipelines
|
||||
spec:
|
||||
- name: IMAGE
|
||||
type: string
|
||||
resources:
|
||||
inputs:
|
||||
- name: src
|
||||
type: git
|
||||
steps:
|
||||
- name: build-and-push
|
||||
workingDir: /workspace/src
|
||||
image: moby/buildkit:latest
|
||||
env:
|
||||
- name: DOCKER_CONFIG
|
||||
value: /root/.docker
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
buildctl-daemonless.sh --debug \
|
||||
build \
|
||||
--progress=plain \
|
||||
--frontend=dockerfile.v0 \
|
||||
--opt filename=Dockerfile \
|
||||
--opt platform=linux/amd64,linux/arm/7,linux/arm64 \
|
||||
--local context=. \
|
||||
--local dockerfile=. \
|
||||
--output type=image,name=$(params.IMAGE),push=true \
|
||||
--export-cache type=inline \
|
||||
--import-cache type=registry,ref=$(params.IMAGE)
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
- name: docker-config
|
||||
mountPath: /root/.docker/config.json
|
||||
subPath: config.json
|
||||
volumes:
|
||||
- name: docker-config
|
||||
secret:
|
||||
secretName: docker-config
|
||||
```
|
26
src/posts/2020-09-17-yaml-multiline.md
Normal file
26
src/posts/2020-09-17-yaml-multiline.md
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
layout: post.html
|
||||
title: "T.I.L. YAML multiline values"
|
||||
summary: "Today I Learnt: YAML multiline values"
|
||||
date: 2020-09-17
|
||||
tags: til yaml
|
||||
|
||||
---
|
||||
|
||||
After using YAML for a long time, for many, many Kubernetes manifest files, I have today learnt that it contains two multiline value types (called scalars):
|
||||
|
||||
```yaml
|
||||
scalarsExample:
|
||||
literalScalar: |
|
||||
Literal scalars use the pipe (`|`) to denote the start of the value with the scope indicated by indentation.
|
||||
All content here is used literally, with newlines preserved.
|
||||
<-- This is the start of the line, the spaces before this aren't included in the literal.
|
||||
This should be used when storing things like file contents (e.g. in a ConfigMap)
|
||||
foldedScalar: >
|
||||
Folded scalars use the greater-than symbol (`>`) to denote the start of the value with the scope indicated by indentation.
|
||||
Unlike literal scalars newlines aren't preserved and instead converted into spaces.
|
||||
<-- This is the start of the line, the spaces before this aren't included in the value.
|
||||
This should be used when you'd normally use a string but the contents are long and wrapping makes it easier to read.
|
||||
```
|
||||
|
||||
> More info: [https://yaml.org/spec/1.2/spec.html#id2760844](https://yaml.org/spec/1.2/spec.html#id2760844)
|
27
src/posts/2020-09-18-golang-split-by-space.md
Normal file
27
src/posts/2020-09-18-golang-split-by-space.md
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
layout: post.html
|
||||
title: "T.I.L. Split on spaces in Go"
|
||||
summary: "Today I Learnt: Split on spaces in Go"
|
||||
date: 2020-09-18
|
||||
tags: til go golang
|
||||
|
||||
---
|
||||
|
||||
While looking to split a multiline and space separated string and not having any luck with `strings.Split()` I came across this somewhat oddly names function:
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
input := `This is
|
||||
a multiline, space
|
||||
separated string`
|
||||
|
||||
output := strings.Fields(input)
|
||||
|
||||
fmt.Println(output) // ["This", "is", "a", "multiline,", "space", "separated", "string"]
|
||||
}
|
||||
```
|
16
src/posts/2020-09-25-kubectl-replace.md
Normal file
16
src/posts/2020-09-25-kubectl-replace.md
Normal file
File diff suppressed because one or more lines are too long
12
src/posts/2020-10-03-dont-reuse-keys.md
Normal file
12
src/posts/2020-10-03-dont-reuse-keys.md
Normal file
@ -0,0 +1,12 @@
|
||||
---
|
||||
layout: post.html
|
||||
title: "T.I.L. Don't Reuse API Keys"
|
||||
summary: "Today I Learnt: Don't Reuse API Keys"
|
||||
date: 2020-10-03T12:49:37+01:00
|
||||
tags: til cli credentials
|
||||
|
||||
---
|
||||
|
||||
Not a technical post today, more of a reminder to myself not to reuse API keys for different purposes. In this instance I reset the credentials I had labelled "Terraform" which I just so happened to also be using In [Harbor](https://goharbor.io/) to connect to my S3 bucket.
|
||||
|
||||
Que 2 hours of me trying to figure out why I couldn't pull or push any images.
|
35
src/posts/2020-10-05-go-named-return-values.md
Normal file
35
src/posts/2020-10-05-go-named-return-values.md
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
layout: post.html
|
||||
title: "T.I.L. Named returns in Go functions"
|
||||
summary: "Today I Learnt: Named returns in Go functions"
|
||||
date: 2020-10-05T15:50:00
|
||||
tags: til golang
|
||||
|
||||
---
|
||||
|
||||
While debugging some issues I was having with the AWS Golang SDK I discovered it was possible to name your function return values (pointers) and then set them within your function body without needing to explicitly return them at the end.
|
||||
|
||||
E.g.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
var greeting = "Hello, world"
|
||||
|
||||
func main() {
|
||||
fmt.Println(*test())
|
||||
}
|
||||
|
||||
func test() (returnVal *string) {
|
||||
returnVal = &greeting
|
||||
return
|
||||
}
|
||||
```
|
||||
|
||||
Note the single `return` at the end of the function.
|
||||
|
||||
I'm not really sure if this is a useful feature, feels more like it'd make code harder to read and could lead to some pretty nasty unintended mistakes when someone unfamilure with the code comes to make changes. Interesting either way.
|
||||
|
||||
I'd be interested if anyone has any examples of where this kind of thing is beneficial.
|
60
src/posts/2020-10-30-golang-append.md
Normal file
60
src/posts/2020-10-30-golang-append.md
Normal file
@ -0,0 +1,60 @@
|
||||
---
|
||||
layout: post.html
|
||||
title: "T.I.L. Golang's append mutates the provided array"
|
||||
summary: "Today I Learnt: Golang's append mutates the provided array"
|
||||
date: 2020-10-30T12:49:37+01:00
|
||||
tags: til golang
|
||||
|
||||
---
|
||||
|
||||
A word of warning when using `append()` in Golang...
|
||||
|
||||
When using a slice of an array as the first parameter when calling `append` if the length of the resulting array is less than that of the initial array then the values in the initial array will be overridden by the new values being appended.
|
||||
|
||||
For example, if we use `append` to take the first two values from the array called `first` and all the values from the array called `second` we can see that `first` is being mutated unexpectedly.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
first := []int{0, 1, 2, 3, 4, 5, 6}
|
||||
second := []int{4, 5, 6}
|
||||
|
||||
fmt.Println(first)
|
||||
// -> [0 1 2 3 4 5 6]
|
||||
fmt.Println(append(first[:2], second...))
|
||||
// -> [0 1 4 5 6]
|
||||
fmt.Println(first)
|
||||
// -> [0 1 4 5 6 4 5 6]
|
||||
}
|
||||
```
|
||||
|
||||
This is _only_ an issue when the resulting array is shorter than the array passed in as the first parameter.
|
||||
|
||||
**Update:**
|
||||
It turns out this is expected behavior (see [github.com/golang/go/issues/28780#issuecomment-438428780](https://github.com/golang/go/issues/28780#issuecomment-438428780)) and a side-effect of how slices work in Go.
|
||||
|
||||
A slice (what we're producing when using the `[:2]`) can be thought of as a view onto an array. So when making changes to a slice you're really just making changes to that part of the array it is pointed to. By default slices are dynamic in size so if you go past the end of the slice you still continue along the array if it has more entries.
|
||||
|
||||
To avoid this happening you can specify a third value in the slice that sets the fixed length of the slice. E.g.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
first := []int{0, 1, 2, 3, 4, 5, 6}
|
||||
second := []int{4, 5, 6}
|
||||
|
||||
fmt.Println(first)
|
||||
// -> [0 1 2 3 4 5 6]
|
||||
fmt.Println(append(first[:2:2], second...))
|
||||
// -> [0 1 4 5 6]
|
||||
fmt.Println(first)
|
||||
// -> [0 1 2 3 4 5 6]
|
||||
fmt.Println("Much better :)")
|
||||
}
|
||||
```
|
22
src/posts/2020-11-10-favicons.md
Normal file
22
src/posts/2020-11-10-favicons.md
Normal file
@ -0,0 +1,22 @@
|
||||
---
|
||||
layout: post.html
|
||||
title: "T.I.L. How to get the favicon of any site"
|
||||
summary: "Today I Learnt: How to get the favicon of any site"
|
||||
date: 2020-11-10T09:49:37+01:00
|
||||
tags: til
|
||||
|
||||
---
|
||||
|
||||
If you ever find yourself needing to display a small icon for a 3rd party URL but don't want to have to crawl the site to pull out the favicon URL then you can make use of a Google CDN:
|
||||
|
||||
```
|
||||
https://s2.googleusercontent.com/s2/favicons?domain_url=https://marcusnoble.co.uk/
|
||||
```
|
||||
|
||||
Example: ![](https://s2.googleusercontent.com/s2/favicons?domain_url=https://marcusnoble.co.uk/)
|
||||
|
||||
You can even provide any page, not just the root URL.
|
||||
|
||||
e.g. `https://s2.googleusercontent.com/s2/favicons?domain_url=https://marcusnoble.co.uk/2020-11-10-t-i-l-how-to-get-the-favicon-of-any-site/`
|
||||
|
||||
![](https://s2.googleusercontent.com/s2/favicons?domain_url=https://marcusnoble.co.uk/2020-11-10-t-i-l-how-to-get-the-favicon-of-any-site/)
|
14
src/posts/2021-04-20-kubernetes-label-length.md
Normal file
14
src/posts/2021-04-20-kubernetes-label-length.md
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
layout: post.html
|
||||
title: "T.I.L. Kubernetes label length"
|
||||
summary: "Today I Learnt: Kubernetes label length"
|
||||
date: 2021-04-20T15:10:37+01:00
|
||||
tags: til kubernetes
|
||||
|
||||
---
|
||||
|
||||
It turns out that label _values_ in Kubernetes have a limit of 63 characters!
|
||||
|
||||
I discovered this today when none of my nodes seemed to be connecting to the control plane. Eventually discovered the hostname of the node was longer than 63 characters (mainly due to multiple subdomain levels) and so the `kubernetes.io/hostname` label being automtically added to the node was causing Kubernetes to reject it.
|
||||
|
||||
If you hit this like me, the hostname used for the label can be [overridden using the `--hostname-override` flag on kubelet](https://kubernetes.io/docs/reference/labels-annotations-taints/#kubernetesiohostname) or by setting the value of the label yourself with the `--node-labels` flag.
|
78
src/posts/2021-05-11-yaml-key-spaces.md
Normal file
78
src/posts/2021-05-11-yaml-key-spaces.md
Normal file
@ -0,0 +1,78 @@
|
||||
---
|
||||
layout: post.html
|
||||
title: "T.I.L. YAML keys allow for spaces in them"
|
||||
summary: "Today I Learnt: YAML keys allow for spaces in them"
|
||||
date: 2021-05-11
|
||||
tags: til yaml
|
||||
|
||||
---
|
||||
|
||||
While browsing through some of [Frenck's](https://github.com/frenck) [Home Assistant Config](https://github.com/frenck/home-assistant-config) for ideas I came across [this interesting line of YAML](https://github.com/frenck/home-assistant-config/blob/a963e1cb3e2acf7beda2b466b334218ac27ee42f/config/integrations/automation.yaml#L7):
|
||||
|
||||
```yaml
|
||||
---
|
||||
# This handles the loading of my automations
|
||||
#
|
||||
# https://www.home-assistant.io/docs/automation/
|
||||
#
|
||||
automation: !include ../automations.yaml
|
||||
automation split: !include_dir_list ../automations # <--
|
||||
```
|
||||
|
||||
I found myself staring at this for a while, followed by searching the [Home Assistant](https://www.home-assistant.io/) documentation website to see if `split` was a special keyword I wasn't aware of.
|
||||
|
||||
And then it dawned on me! As all JSON is valid YAML, and JSON keys can be pretty much any string it makes sense that YAML supports it.
|
||||
|
||||
The above example converted to JSON using [json2yaml](https://www.json2yaml.com/convert-yaml-to-json) looks like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"automation": "../automations.yaml",
|
||||
"automation split": "../automations"
|
||||
}
|
||||
```
|
||||
|
||||
Knowing this, I decided to try out a few more variations to see what works...
|
||||
|
||||
YAML:
|
||||
```yaml
|
||||
---
|
||||
123: Valid
|
||||
---: also valid
|
||||
5.5: yup! this too
|
||||
#how about this?: nope, this is treated as a comment
|
||||
//: yeah, totally valid
|
||||
✨: yep!
|
||||
[1]: Works
|
||||
[1, 2]: Still works, treated as string
|
||||
{another}: This one is interesting
|
||||
```
|
||||
|
||||
JSON:
|
||||
```json
|
||||
{
|
||||
"123": "Valid",
|
||||
"---": "also valid",
|
||||
"5.5": "yup! this too",
|
||||
"//": "yeah, totally valid",
|
||||
"✨": "yep!",
|
||||
"[1]": "Works",
|
||||
"[1, 2]": "Still works, treated as string",
|
||||
"{\"another\"=>nil}": "This one is interesting"
|
||||
}
|
||||
```
|
||||
|
||||
Depending on the library used, varying results can be generated. For example, [yamlonline](https://yamlonline.com/) returns the following for the same input:
|
||||
|
||||
```json
|
||||
{
|
||||
"1": "Works",
|
||||
"123": "Valid",
|
||||
"---": "also valid",
|
||||
"5.5": "yup! this too",
|
||||
"//": "yeah, totally valid",
|
||||
"✨": "yep!",
|
||||
"1,2": "Still works, treated as string",
|
||||
"[object Object]": "This one is interesting"
|
||||
}
|
||||
```
|
41
src/posts/2021-08-04-getopts.md
Normal file
41
src/posts/2021-08-04-getopts.md
Normal file
@ -0,0 +1,41 @@
|
||||
---
|
||||
layout: post.html
|
||||
title: "T.I.L. CLI flag handling in Bash using getopts"
|
||||
summary: "Today I Learnt: CLI flag handling in Bash using getopts"
|
||||
date: 2021-08-04T20:49:37+01:00
|
||||
tags: til bash
|
||||
|
||||
---
|
||||
|
||||
I'm not sure how I've never come across this before but while looking through the [Scaleway Kosmos](https://www.scaleway.com/en/betas/#kuberneteskosmos) multi-cloud init script I dicovered the [`getopts`](https://www.man7.org/linux/man-pages/man1/getopts.1p.html) utility.
|
||||
|
||||
`getopts` makes it easier to parse arguments passed to a shell script by defining which letters your script supports. It supports both boolean and string style arguments but only supports single letter flags. (e.g. `-h` and not `--help`)
|
||||
|
||||
Example usage:
|
||||
|
||||
```sh
|
||||
#!/bin/bash
|
||||
|
||||
NAME="World"
|
||||
FORCE=false
|
||||
|
||||
showHelp() {
|
||||
echo "Usage: example.sh [args]"
|
||||
exit 0
|
||||
}
|
||||
|
||||
while getopts 'hfn:' FLAG
|
||||
do
|
||||
case $FLAG in
|
||||
h) showHelp ;;
|
||||
f) FORCE=true ;;
|
||||
n) NAME=$OPTARG ;;
|
||||
*) echo "Unsupported argument flag passed" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "Hello, $NAME"
|
||||
|
||||
```
|
||||
|
||||
Notice the `:` following the `n`? That indicates that a value should follow the argument flag (`n` in this example) and will be made available as the `OPTARG` variable.
|
Loading…
Reference in New Issue
Block a user