Switch to gruvbox theme
111
.gitignore
vendored
@@ -1,2 +1,113 @@
|
||||
.hugo_build.lock
|
||||
.vscode
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
.temp
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
### Node Patch ###
|
||||
# Serverless Webpack directories
|
||||
.webpack/
|
||||
|
||||
# Optional stylelint cache
|
||||
|
||||
# SvelteKit build / generate output
|
||||
.svelte-kit
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/hugo,node
|
||||
|
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
||||
[submodule "themes/hugo-video"]
|
||||
path = themes/hugo-video
|
||||
url = https://github.com/martignoni/hugo-video.git
|
6
Makefile
@@ -10,7 +10,8 @@ endif
|
||||
.RECIPEPREFIX = >
|
||||
|
||||
build: clean
|
||||
> hugo
|
||||
> npm ci
|
||||
> hugo --minify
|
||||
|
||||
clean:
|
||||
> rm -rf public/
|
||||
@@ -19,9 +20,6 @@ clean:
|
||||
server:
|
||||
> hugo server --buildDrafts
|
||||
|
||||
## index-pagefind: Not yet implemented
|
||||
index-pagefind:
|
||||
> npx pagefind --source "public"
|
||||
|
||||
## help: Print this help message
|
||||
help:
|
||||
|
@@ -1,35 +1,9 @@
|
||||
---
|
||||
title: "{{ replace .TranslationBaseName "-" " " | title }}"
|
||||
date: {{ .Date }}
|
||||
lastmod: {{ .Date }}
|
||||
title: "{{ humanize .Name | title }}"
|
||||
date: "{{ .Date }}"
|
||||
draft: true
|
||||
keywords: []
|
||||
description: ""
|
||||
tags: []
|
||||
categories: []
|
||||
author: ""
|
||||
|
||||
# You can also close(false) or open(true) something for this content.
|
||||
# P.S. comment can only be closed
|
||||
comment: false
|
||||
comments: true
|
||||
toc: false
|
||||
autoCollapseToc: false
|
||||
postMetaInFooter: false
|
||||
hiddenFromHomePage: false
|
||||
# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright."
|
||||
contentCopyright: false
|
||||
reward: false
|
||||
mathjax: false
|
||||
mathjaxEnableSingleDollar: false
|
||||
|
||||
flowchartDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
|
||||
sequenceDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
|
||||
---
|
||||
|
||||
<!--more-->
|
||||
|
@@ -1,15 +0,0 @@
|
||||
.hanchor {
|
||||
visibility: hidden;
|
||||
color: silver;
|
||||
font-size: 100%;
|
||||
transition: 0.2s;
|
||||
padding-left: 8px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
h2:hover a,
|
||||
h3:hover a,
|
||||
h4:hover a {
|
||||
visibility: visible;
|
||||
text-decoration: none;
|
||||
}
|
10
assets/jsconfig.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"*": [
|
||||
"../node_modules/prismjs/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
93
config.yaml
@@ -1,67 +1,54 @@
|
||||
baseurl: /
|
||||
staticDir: static
|
||||
baseurl: "https://davegallant.ca"
|
||||
languageCode: en-us
|
||||
googleAnalytics: G-V8WJDERTX9
|
||||
copyright: Dave Gallant
|
||||
preserveTaxonomyNames: true
|
||||
pygmentsstyle: nord
|
||||
pygmentscodefences: true
|
||||
pygmentscodefencesguesssyntax: true
|
||||
theme:
|
||||
- archie
|
||||
- hugo-video
|
||||
title: davegallant
|
||||
|
||||
params:
|
||||
mode: toggle
|
||||
useCDN: true
|
||||
subtitle: "A personal blog"
|
||||
mathjax: true
|
||||
katex: true
|
||||
author: Dave Gallant
|
||||
subtitle: Software Engineer
|
||||
favicon: https://davegallant.ca/favicon.ico
|
||||
|
||||
favicon: https://davegallant.ca/favicon.ico
|
||||
logo:
|
||||
text: davegallant.ca
|
||||
url: /
|
||||
|
||||
kofi:
|
||||
|
||||
customcss:
|
||||
- css/custom.css
|
||||
|
||||
social:
|
||||
- name: Email
|
||||
icon: at-sign
|
||||
url: 'mailto:me@davegallant.ca'
|
||||
- name: LinkTree
|
||||
icon: compass
|
||||
url: 'https://linktr.ee/davegallant'
|
||||
- name: GitHub
|
||||
icon: github
|
||||
url: 'https://github.com/davegallant'
|
||||
- name: Mastodon
|
||||
icon: speaker
|
||||
url: https://mastodon.social/@davegallant
|
||||
- name: LinkedIn
|
||||
icon: linkedin
|
||||
url: https://www.linkedin.com/in/dave-gallant/
|
||||
|
||||
comments:
|
||||
utterances:
|
||||
enable: true
|
||||
issueTerm: "pathname"
|
||||
github:
|
||||
username: davegallant
|
||||
repository: davegallant.github.io
|
||||
comments:
|
||||
utterances:
|
||||
enable: true
|
||||
issueTerm: "pathname"
|
||||
github:
|
||||
username: davegallant
|
||||
repository: davegallant.github.io
|
||||
|
||||
menu:
|
||||
main:
|
||||
- name: Posts
|
||||
url: /
|
||||
weight: 1
|
||||
- name: About
|
||||
url: /about
|
||||
weight: 2
|
||||
- name: RSS
|
||||
url: /index.xml
|
||||
weight: 3
|
||||
weight: 1
|
||||
|
||||
permalinks:
|
||||
post: '/blog/:year/:month/:day/:slug/'
|
||||
post: "/blog/:year/:month/:day/:slug/"
|
||||
|
||||
module:
|
||||
imports:
|
||||
- path: github.com/davegallant/hugo-theme-gruvbox
|
||||
- path: github.com/schnerring/hugo-mod-json-resume
|
||||
mounts:
|
||||
- source: node_modules/simple-icons/icons
|
||||
target: assets/simple-icons
|
||||
- source: assets
|
||||
target: assets
|
||||
- source: layouts
|
||||
target: layouts
|
||||
- source: static
|
||||
target: static
|
||||
- source: node_modules/prismjs
|
||||
target: assets/prismjs
|
||||
- source: node_modules/prism-themes/themes
|
||||
target: assets/prism-themes
|
||||
- source: node_modules/typeface-fira-code/files
|
||||
target: static/fonts
|
||||
- source: node_modules/typeface-roboto-slab/files
|
||||
target: static/fonts
|
||||
- source: node_modules/@tabler/icons/icons
|
||||
target: assets/tabler-icons
|
||||
|
@@ -1,10 +0,0 @@
|
||||
---
|
||||
title: About
|
||||
weight: -210
|
||||
disable_comments: true
|
||||
hide_date: true
|
||||
---
|
||||
|
||||
I'm a software tinkerer with a passion for infrastructure, tooling, security, and coffee.
|
||||
|
||||
Feel free to reach out at [me@davegallant.ca](mailto:me@davegallant.ca).
|
@@ -2,8 +2,7 @@
|
||||
title: "AppGate SDP on Arch Linux"
|
||||
date: 2020-03-16T22:00:15-04:00
|
||||
draft: false
|
||||
keywords: ['linux', 'vpn']
|
||||
description: ""
|
||||
comments: true
|
||||
tags: ['linux', 'vpn', 'python']
|
||||
author: "Dave Gallant"
|
||||
---
|
||||
|
@@ -3,37 +3,10 @@ title: "Automatically rotating AWS access keys"
|
||||
date: 2021-09-17T12:48:33-04:00
|
||||
lastmod: 2021-09-17T12:48:33-04:00
|
||||
draft: false
|
||||
keywords: []
|
||||
description: ""
|
||||
comments: true
|
||||
tags: ['aws', 'python', 'security', 'aws-vault']
|
||||
categories: []
|
||||
author: ""
|
||||
|
||||
# You can also close(false) or open(true) something for this content.
|
||||
# P.S. comment can only be closed
|
||||
comment: false
|
||||
toc: false
|
||||
autoCollapseToc: false
|
||||
postMetaInFooter: false
|
||||
hiddenFromHomePage: false
|
||||
# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright."
|
||||
contentCopyright: false
|
||||
reward: false
|
||||
mathjax: false
|
||||
mathjaxEnableSingleDollar: false
|
||||
|
||||
flowchartDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
|
||||
sequenceDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
|
||||
---
|
||||
|
||||
<!--more-->
|
||||
|
||||
Rotating credentials is a security best practice. This morning, I read a question about automatically rotating AWS Access Keys without having to go through the hassle of navigating the AWS console. There are some existing solutions already, but I decided to write a [script](https://gist.github.com/davegallant/2c042686a78684a657fe99e20fa7a924#file-aws_access_key_rotator-py) since it was incredibly simple. The script could be packed up as a systemd/launchd service to continually rotate access keys in the background.
|
||||
|
||||
In the longer term, migrating my local workflows to [aws-vault](https://github.com/99designs/aws-vault) seems like a more secure solution. This would mean that credentials (even temporary session credentials) never have to be written in plaintext to disk (i.e. where [AWS suggests](https://docs.aws.amazon.com/sdkref/latest/guide/file-location.html)). Any existing applications, such as terraform, could be have their credentials passed to them from aws-vault, which retrieves them from the OS's secure keystore. There is even a [rotate command](https://github.com/99designs/aws-vault/blob/master/USAGE.md#rotating-credentials) included.
|
||||
|
@@ -2,39 +2,14 @@
|
||||
title: "Backing up gmail with Synology"
|
||||
date: 2022-03-13T18:49:10-04:00
|
||||
lastmod: 2022-03-13T18:49:10-04:00
|
||||
comments: true
|
||||
draft: false
|
||||
keywords: []
|
||||
description: ""
|
||||
tags: ['degoogle', 'synology', 'gmail', 'backup', 'ransomware']
|
||||
categories: []
|
||||
author: ""
|
||||
|
||||
# You can also close(false) or open(true) something for this content.
|
||||
# P.S. comment can only be closed
|
||||
comment: false
|
||||
toc: false
|
||||
autoCollapseToc: false
|
||||
postMetaInFooter: false
|
||||
hiddenFromHomePage: false
|
||||
# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright."
|
||||
contentCopyright: false
|
||||
reward: false
|
||||
mathjax: false
|
||||
mathjaxEnableSingleDollar: false
|
||||
|
||||
flowchartDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
|
||||
sequenceDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
|
||||
tags: ["degoogle", "synology", "gmail", "backup", "ransomware"]
|
||||
---
|
||||
|
||||
<!--more-->
|
||||
I've used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.
|
||||
|
||||
I've used gmail since the beta launched touting a whopping 1GB of storage. I thought this was a massive leap in email technology at the time. I was lucky enough to get an invite fairly quickly. Not suprisingly, I have many years of emails, attachments, and photos. I certainly do not want to lose the content of many of these emails. Despite the redundancy of the data that Google secures, I still feel better retaining a copy of this data on my own physical machines.
|
||||
<!--more-->
|
||||
|
||||
The thought of completely de-googling has crossed my mind on occassion. Convenience, coupled with my admiration for Google engineering, has prevented me from doing so thus far. Though, I may end up doing so at some point in the future.
|
||||
|
||||
@@ -42,7 +17,7 @@ The thought of completely de-googling has crossed my mind on occassion. Convenie
|
||||
|
||||
Synology products are reasonably priced for what you get (essentially a cloud-in-a-box) and there is very little maintenance required. I've recently been in interested in syncing and snapshotting my personal data. I've setup [Synology's Cloud Sync](https://www.synology.com/en-ca/dsm/feature/cloud_sync) and keep copies of most of my cloud data.
|
||||
|
||||
I've used tools such as [gmvault](http://www.gmvault.org) with success in the past. Setting this up on a cron seems like a viable option. However, I don't really need a lot of the features it offers and do not plan to restore this data to another account.
|
||||
I've used tools such as [gmvault](http://www.gmvault.org) with success in the past. Setting this up on a cron seems like a viable option. However, I don't really need a lot of the features it offers and do not plan to restore this data to another account.
|
||||
|
||||
Synology's MailPlus seems to be a good candidate for backing up this data. By enabling POP3 fetching, it's possible to fetch all existing emails, as well as periodically fetch all new emails. If a disaster ever did occur, having these emails would be beneficial, as they are an extension of my memory bank.
|
||||
|
||||
@@ -62,7 +37,7 @@ After this, mail started coming in.
|
||||
|
||||

|
||||
|
||||
After fetching 19 years worth of emails, I tried searching for some emails. It only took a few seconds to search through ~50K emails, which is a relief if I ever did have to search for something important.
|
||||
After fetching 19 years worth of emails, I tried searching for some emails. It only took a few seconds to search through ~50K emails, which is a relief if I ever did have to search for something important.
|
||||
|
||||
## Securing Synology
|
||||
|
||||
|
@@ -3,39 +3,14 @@ title: "Replacing docker with podman on macOS (and Linux)"
|
||||
date: 2021-10-11T10:43:35-04:00
|
||||
lastmod: 2021-10-11T10:43:35-04:00
|
||||
draft: false
|
||||
keywords: []
|
||||
description: ""
|
||||
tags: ['docker', 'podman', 'containers']
|
||||
author: ""
|
||||
|
||||
# You can also close(false) or open(true) something for this content.
|
||||
# P.S. comment can only be closed
|
||||
comment: false
|
||||
toc: false
|
||||
autoCollapseToc: false
|
||||
postMetaInFooter: false
|
||||
hiddenFromHomePage: false
|
||||
# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright."
|
||||
contentCopyright: false
|
||||
reward: false
|
||||
mathjax: false
|
||||
mathjaxEnableSingleDollar: false
|
||||
|
||||
flowchartDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
|
||||
sequenceDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
|
||||
comments: true
|
||||
tags: ["docker", "podman", "containers"]
|
||||
---
|
||||
|
||||
<!--more-->
|
||||
|
||||
|
||||
There are a number of reasons why you might want to replace docker, especially on macOS. The following feature bundled in Docker Desktop might have motivated you enough to consider replacing docker:
|
||||
|
||||
<!--more-->
|
||||
|
||||
{{< tweet 1388586550682861568 >}}
|
||||
|
||||
Docker has been one of the larger influencers in the container world, helping to standardize the [OCI Image Format Specification](https://github.com/opencontainers/image-spec/blob/main/spec.md). For many developers, containers have become synonymous with terms like `docker` and `Dockerfile` (a file containing build instructions for a container image). Docker has certainly made it very convenient to build and run containers, but it is not the only solution for doing so.
|
||||
@@ -85,7 +60,7 @@ Copying config sha256:14119a10abf4669e8cdbdff324a9f9605d99697215a0d21c360fe8dfa8
|
||||
Writing manifest to image destination
|
||||
Storing signatures
|
||||
14119a10abf4669e8cdbdff324a9f9605d99697215a0d21c360fe8dfa8471bab
|
||||
````
|
||||
```
|
||||
|
||||
> If you're having an issue pulling images, you may need to remove `~/.docker/config.json` or remove the set of auths in the configuration as mentioned [here](https://stackoverflow.com/a/69121873/1191286).
|
||||
|
||||
@@ -118,7 +93,7 @@ alias docker=podman
|
||||
|
||||
### podman-compose
|
||||
|
||||
You may be wondering: what about docker-compose? Well, there *claims* to be a drop-in replacement for it: [podman-compose](https://github.com/containers/podman-compose).
|
||||
You may be wondering: what about docker-compose? Well, there _claims_ to be a drop-in replacement for it: [podman-compose](https://github.com/containers/podman-compose).
|
||||
|
||||
```sh
|
||||
pip3 install --user podman-compose
|
||||
@@ -168,5 +143,4 @@ One caveat to mention is that there isn't an official graphical user interface f
|
||||
|
||||
> Update: After further usage, bind mounts do not seem to work out of the box when the client and host are on different machines. A rather involved solution using [sshfs](https://en.wikipedia.org/wiki/SSHFS) was shared [here](https://github.com/containers/podman/issues/8016#issuecomment-920015800).
|
||||
|
||||
|
||||
I had been experimenting with Podman on Linux before writing this, but after listening to this [podcast episode](https://kubernetespodcast.com/episode/164-podman/), I was inspired to give Podman a try on macOS.
|
||||
|
@@ -3,29 +3,8 @@ title: "Running K3s in LXC on Proxmox"
|
||||
date: 2021-11-14T10:07:03-05:00
|
||||
lastmod: 2021-11-14T10:07:03-05:00
|
||||
draft: false
|
||||
keywords: []
|
||||
description: ""
|
||||
comments: true
|
||||
tags: ["k3s", "proxmox", "lxc", "self-hosted"]
|
||||
categories: []
|
||||
author: ""
|
||||
|
||||
comment: false
|
||||
toc: false
|
||||
autoCollapseToc: false
|
||||
postMetaInFooter: false
|
||||
hiddenFromHomePage: false
|
||||
contentCopyright: false
|
||||
reward: false
|
||||
mathjax: false
|
||||
mathjaxEnableSingleDollar: false
|
||||
|
||||
flowchartDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
|
||||
sequenceDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
---
|
||||
|
||||
It has been a while since I've actively used Kubernetes and wanted to explore the evolution of tools such as [Helm](https://helm.sh) and [Tekton](https://tekton.dev). I decided to deploy [K3s](https://k3s.io), since I've had success with deploying it on resource-contrained Raspberry Pis in the past. I thought that this time it'd be convenient to have K3s running in a LXC container on Proxmox. This would allow for easy snapshotting of the entire Kubernetes deployment. LXC containers also provide an efficient way to use a machine's resources.
|
||||
|
@@ -1,40 +1,17 @@
|
||||
---
|
||||
title: "Setting up Gitea Actions with Tailscale"
|
||||
date: 2023-12-10T17:22:11-05:00
|
||||
comments: true
|
||||
lastmod: 2023-12-10T17:22:11-05:00
|
||||
draft: false
|
||||
keywords: []
|
||||
description: ""
|
||||
tags: ["gitea", "gitea actions", "github actions", "tailscale", "self-hosted"]
|
||||
categories: []
|
||||
author: ""
|
||||
|
||||
# You can also close(false) or open(true) something for this content.
|
||||
# P.S. comment can only be closed
|
||||
comment: false
|
||||
toc: false
|
||||
autoCollapseToc: false
|
||||
postMetaInFooter: false
|
||||
hiddenFromHomePage: false
|
||||
# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright."
|
||||
contentCopyright: false
|
||||
reward: false
|
||||
mathjax: false
|
||||
mathjaxEnableSingleDollar: false
|
||||
|
||||
flowchartDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
|
||||
sequenceDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
---
|
||||
|
||||
<!--more-->
|
||||
|
||||
In this post I'll go through the process of setting up Gitea Actions and [Tailscale](https://tailscale.com/), unlocking a simple and secure way to automate workflows.
|
||||
|
||||
<!--more-->
|
||||
|
||||
## What is Gitea?
|
||||
|
||||
[Gitea](https://about.gitea.com/) is a lightweight and fast git server that has much of the same look and feel as github. I have been using it in my homelab to mirror repositories hosted on other platforms such as github and gitlab. These mirrors take advantage of the decentralized nature of git by serving as "backups". One of the main reasons I hadn't been using it more often was due to the lack of integrated CI/CD. This is no longer the case.
|
||||
@@ -209,7 +186,7 @@ jobs:
|
||||
|
||||
And voilà:
|
||||
|
||||
{{< video src="gitea-workflow" >}}
|
||||
{{< video poster="gitea-workflow" >}}
|
||||
|
||||
You may be wondering how the gitea runner is allowed to connect to the other hosts using ansible? Well, the nodes are in the same tailnet and have [tailscale ssh](https://tailscale.com/tailscale-ssh) enabled.
|
||||
|
||||
|
@@ -3,8 +3,7 @@ title: "Using AKS and SOCKS to connect to a private Azure DB"
|
||||
date: 2023-05-22T16:31:29-04:00
|
||||
lastmod: 2023-05-22T16:31:29-04:00
|
||||
draft: false
|
||||
keywords: []
|
||||
description: ""
|
||||
comments: true
|
||||
tags:
|
||||
[
|
||||
"aks",
|
||||
@@ -20,36 +19,12 @@ tags:
|
||||
"socat",
|
||||
"socks",
|
||||
]
|
||||
categories: []
|
||||
author: ""
|
||||
|
||||
# You can also close(false) or open(true) something for this content.
|
||||
# P.S. comment can only be closed
|
||||
comment: false
|
||||
toc: false
|
||||
autoCollapseToc: false
|
||||
postMetaInFooter: false
|
||||
hiddenFromHomePage: false
|
||||
# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright."
|
||||
contentCopyright: false
|
||||
reward: false
|
||||
mathjax: false
|
||||
mathjaxEnableSingleDollar: false
|
||||
|
||||
flowchartDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
|
||||
sequenceDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
---
|
||||
|
||||
I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I'd rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I'd like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.
|
||||
|
||||
<!--more-->
|
||||
|
||||
## The Problem
|
||||
|
||||
I ran into a roadblock recently where I wanted to be able to conveniently connect to a managed postgres database within Azure that was not running on public subnets. And by conveniently, I mean that I'd rather not have to spin up an ephemeral virtual machine running in the same network and proxy the connection, and I'd like to use a local client (preferably with a GUI). After several web searches, it became evident that Azure does not readily provide much tooling to support this.
|
||||
|
||||
## Go Public?
|
||||
|
||||
|
@@ -3,8 +3,7 @@ title: "Virtualizing my router with pfSense"
|
||||
date: 2022-04-02T18:50:09-04:00
|
||||
lastmod: 2022-04-02T18:50:09-04:00
|
||||
draft: false
|
||||
keywords: []
|
||||
description: ""
|
||||
comments: true
|
||||
tags:
|
||||
[
|
||||
"pfsense",
|
||||
@@ -15,37 +14,12 @@ tags:
|
||||
"vlan",
|
||||
"self-hosted",
|
||||
]
|
||||
categories: []
|
||||
author: ""
|
||||
|
||||
# You can also close(false) or open(true) something for this content.
|
||||
# P.S. comment can only be closed
|
||||
comment: false
|
||||
toc: false
|
||||
autoCollapseToc: false
|
||||
postMetaInFooter: false
|
||||
hiddenFromHomePage: false
|
||||
# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright."
|
||||
contentCopyright: false
|
||||
reward: false
|
||||
mathjax: false
|
||||
mathjaxEnableSingleDollar: false
|
||||
|
||||
flowchartDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
|
||||
sequenceDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
---
|
||||
|
||||
<!--more-->
|
||||
|
||||
## The problem
|
||||
|
||||
My aging router has been running [OpenWrt](https://en.wikipedia.org/wiki/OpenWrt) for years and for the most part has been quite reliable. OpenWrt is an open-source project used on embedded devices to route network traffic. It supports many different configurations and there exists a [large index of packages](https://openwrt.org/packages/index/start). Ever since I've connected some standalone wireless access points, I've had less of a need for an off-the-shelf all-in-one wireless router combo. I've also recently been experiencing instability with my router (likely the result of a combination of configuration tweaking and firmware updating). OpenWrt has served me well, but it is time to move on!
|
||||
|
||||
<!--more-->
|
||||
|
||||
## pfSense
|
||||
|
||||
I figured this would be a good opportunity to try [pfSense](https://en.wikipedia.org/wiki/PfSense). I've heard nothing but positive things about pfSense and the fact it's been around since 2004, based on FreeBSD, and written in PHP gave me the impression that it would be relatively stable (and I'd expect nothing less because it has an important job to do!). pfSense can be run on many different machines, and there are even some [officially supported appliances](https://www.netgate.com/appliances). Since I already have a machine running Proxmox, why not just run it in a VM? It'd allow for automatic snapshotting of the machine. There is a good [video](https://www.youtube.com/watch?v=hdoBQNI_Ab8) on this by Techno Tim. Tim has a lot of good videos, and this one is about virtualizing pfSense.
|
||||
|
@@ -3,8 +3,7 @@ title: "Watching YouTube in private"
|
||||
date: 2022-12-10T21:46:55-05:00
|
||||
lastmod: 2022-12-10T21:46:55-05:00
|
||||
draft: false
|
||||
keywords: []
|
||||
description: ""
|
||||
comments: true
|
||||
tags:
|
||||
[
|
||||
"invidious",
|
||||
@@ -15,35 +14,12 @@ tags:
|
||||
"privacy",
|
||||
"self-hosted",
|
||||
]
|
||||
categories: []
|
||||
author: ""
|
||||
|
||||
# You can also close(false) or open(true) something for this content.
|
||||
# P.S. comment can only be closed
|
||||
comment: false
|
||||
toc: false
|
||||
autoCollapseToc: false
|
||||
postMetaInFooter: false
|
||||
hiddenFromHomePage: false
|
||||
# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright."
|
||||
contentCopyright: false
|
||||
reward: false
|
||||
mathjax: false
|
||||
mathjaxEnableSingleDollar: false
|
||||
|
||||
flowchartDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
|
||||
sequenceDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
---
|
||||
|
||||
<!--more-->
|
||||
|
||||
I recently stumbled upon [yewtu.be](https://yewtu.be) and found it intriguing. It not only allows you to watch YouTube without _being on YouTube_, but it also allows you to create an account and subscribe to channels without a Google account. What sort of wizardry is going on under the hood? It turns out that it's a hosted instance of [invidious](https://invidious.io/).
|
||||
|
||||
<!--more-->
|
||||
|
||||

|
||||
|
||||
The layout is simple, and **JavaScript is not required**.
|
||||
|
@@ -3,21 +3,7 @@ title: "What to do with a homelab"
|
||||
date: 2021-09-06T01:12:54-04:00
|
||||
lastmod: 2021-09-06T01:12:54-04:00
|
||||
draft: false
|
||||
keywords: []
|
||||
description: ""
|
||||
tags:
|
||||
[
|
||||
"tailscale",
|
||||
"homelab",
|
||||
"netdata",
|
||||
"jellyfin",
|
||||
"plex",
|
||||
"pihole",
|
||||
"virtualization",
|
||||
"adguard",
|
||||
"grafana",
|
||||
"self-hosted",
|
||||
]
|
||||
comments: true
|
||||
author: "Dave Gallant"
|
||||
---
|
||||
|
||||
|
@@ -3,37 +3,12 @@ title: "Why I threw out my dotfiles"
|
||||
date: 2021-09-08T00:42:33-04:00
|
||||
lastmod: 2021-09-08T00:42:33-04:00
|
||||
draft: false
|
||||
keywords: []
|
||||
description: ""
|
||||
comments: true
|
||||
tags: ['nix', 'dotfiles', 'home-manager']
|
||||
categories: []
|
||||
author: ""
|
||||
|
||||
# You can also close(false) or open(true) something for this content.
|
||||
# P.S. comment can only be closed
|
||||
comment: false
|
||||
toc: false
|
||||
autoCollapseToc: false
|
||||
postMetaInFooter: false
|
||||
hiddenFromHomePage: false
|
||||
# You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright."
|
||||
contentCopyright: false
|
||||
reward: false
|
||||
mathjax: false
|
||||
mathjaxEnableSingleDollar: false
|
||||
|
||||
flowchartDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
|
||||
sequenceDiagrams:
|
||||
enable: false
|
||||
options: ""
|
||||
|
||||
---
|
||||
Over the years I have collected a number of dotfiles that I have shared across both Linux and macOS machines (`~/.zshrc`, `~/.config/git/config`, `~/.config/tmux/tmux.conf`, etc). I have tried several different ways to manage them, including [bare git repos](https://www.atlassian.com/git/tutorials/dotfiles) and utilities such as [GNU Stow](https://www.gnu.org/software/stow/). These solutions work well enough, but I have since found what I would consider a much better solution for organizing user configuration: [home-manager](https://github.com/nix-community/home-manager).
|
||||
|
||||
<!--more-->
|
||||
Over the years I have collected a number of dotfiles that I have shared across both Linux and macOS machines (`~/.zshrc`, `~/.config/git/config`, `~/.config/tmux/tmux.conf`, etc). I have tried several different ways to manage them, including [bare git repos](https://www.atlassian.com/git/tutorials/dotfiles) and utilities such as [GNU Stow](https://www.gnu.org/software/stow/). These solutions work well enough, but I have since found what I would consider a much better solution for organizing user configuration: [home-manager](https://github.com/nix-community/home-manager).
|
||||
|
||||
## What is home-manager?
|
||||
|
||||
|
27
data/json_resume/en.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"basics": {
|
||||
"name": "Dave Gallant",
|
||||
"label": "Software Engineer",
|
||||
"image": "",
|
||||
"email": "me@davegallant.ca",
|
||||
"summary": "I'm a software tinkerer passionate about infra, security and self-hosting 👋.",
|
||||
"profiles": [
|
||||
{
|
||||
"network": "LinkTree",
|
||||
"url": "https://linktr.ee/davegallant"
|
||||
},
|
||||
{
|
||||
"network": "GitHub",
|
||||
"url": "https://github.com/davegallant"
|
||||
},
|
||||
{
|
||||
"network": "Mastodon",
|
||||
"url": "https://mastodon.social/@davegallant"
|
||||
},
|
||||
{
|
||||
"network": "LinkedIn",
|
||||
"url": "https://www.linkedin.com/in/dave-gallant"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
9
go.mod
Normal file
@@ -0,0 +1,9 @@
|
||||
module davegallant.github.io
|
||||
|
||||
go 1.21.5
|
||||
|
||||
require (
|
||||
github.com/davegallant/hugo-theme-gruvbox v0.0.0-20240102030224-3e3d39381e83 // indirect
|
||||
github.com/schnerring/hugo-mod-json-resume v0.0.0-20231224014047-e651a547c19a // indirect
|
||||
github.com/schnerring/hugo-theme-gruvbox v0.0.0-20231222001142-c40bfccc26fe // indirect
|
||||
)
|
6
go.sum
Normal file
@@ -0,0 +1,6 @@
|
||||
github.com/davegallant/hugo-theme-gruvbox v0.0.0-20240102030224-3e3d39381e83 h1:1K2zeS/GlzUztodRODqVdT0L53So3oKQl2W6xv3hk3k=
|
||||
github.com/davegallant/hugo-theme-gruvbox v0.0.0-20240102030224-3e3d39381e83/go.mod h1:BQehNdf/SB/+bCc031OVsLECIgB9ZaN1dfUFKTeOIuo=
|
||||
github.com/schnerring/hugo-mod-json-resume v0.0.0-20231224014047-e651a547c19a h1:EZRiOf0iW5k9lycVv3LngzSsGUxDRszYS4U7ea2r8RY=
|
||||
github.com/schnerring/hugo-mod-json-resume v0.0.0-20231224014047-e651a547c19a/go.mod h1:5dixHC0WHu0w2Aqb8hsOCrIU1OBYr1w5Q6HZAmTub7Q=
|
||||
github.com/schnerring/hugo-theme-gruvbox v0.0.0-20231222001142-c40bfccc26fe h1:YFCe/83618UT24IqSn7Ka0TSSZ54BNvDJ7n0WzxWgsg=
|
||||
github.com/schnerring/hugo-theme-gruvbox v0.0.0-20231222001142-c40bfccc26fe/go.mod h1:ZEP0AB4v1k845Jmx9XmOY39CuR7Zud/owFh8wRGgeZg=
|
@@ -1,8 +1,17 @@
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="https://storage.ko-fi.com/cdn/widget/Widget_2.js"
|
||||
></script>
|
||||
<script type="text/javascript">
|
||||
kofiwidget2.init("Buy me a coffee", "#458588", "F1F2S4LWI");
|
||||
kofiwidget2.draw();
|
||||
</script>
|
||||
|
||||
{{- $config := .Site.Params.comments -}}
|
||||
|
||||
{{- $utterancesEnabled := $config.utterances.enable -}}
|
||||
|
||||
{{- if and ( $utterancesEnabled ) ( not .Params.disable_comments) -}}
|
||||
{{- if and ( $utterancesEnabled ) -}}
|
||||
<section id='comments' class='comments'>
|
||||
<div class='container sep-before'>
|
||||
<div class='comments'>
|
6774
package-lock.json
generated
Normal file
4
package.hugo.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "davegallant.github.io",
|
||||
"version": "0.1.0"
|
||||
}
|
68
package.json
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"comments": {
|
||||
"dependencies": {
|
||||
"@tabler/icons": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"flexsearch": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"normalize.css": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"prism-themes": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"prismjs": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"simple-icons": "github.com/schnerring/hugo-mod-json-resume",
|
||||
"typeface-fira-code": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"typeface-roboto-slab": "github.com/davegallant/hugo-theme-gruvbox"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fullhuman/postcss-purgecss": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"cssnano": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"eslint": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"eslint-config-prettier": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"eslint-plugin-prettier": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"husky": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"lint-staged": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"markdownlint-cli": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"postcss": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"postcss-cli": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"postcss-custom-media": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"postcss-import": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"postcss-nesting": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"postcss-preset-env": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"postcss-url": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"prettier": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"prettier-plugin-go-template": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"stylelint": "github.com/davegallant/hugo-theme-gruvbox",
|
||||
"stylelint-prettier": "github.com/davegallant/hugo-theme-gruvbox"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@tabler/icons": "^2.44.0",
|
||||
"flexsearch": "^0.7.31",
|
||||
"normalize.css": "^8.0.1",
|
||||
"prism-themes": "^1.9.0",
|
||||
"prismjs": "^1.29.0",
|
||||
"simple-icons": "^10.4.0",
|
||||
"typeface-fira-code": "^1.1.13",
|
||||
"typeface-roboto-slab": "^1.1.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fullhuman/postcss-purgecss": "^5.0.0",
|
||||
"cssnano": "^6.0.2",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-prettier": "^5.1.1",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^15.2.0",
|
||||
"markdownlint-cli": "^0.38.0",
|
||||
"postcss": "^8.4.32",
|
||||
"postcss-cli": "^11.0.0",
|
||||
"postcss-custom-media": "^10.0.2",
|
||||
"postcss-import": "^15.1.0",
|
||||
"postcss-nesting": "^12.0.2",
|
||||
"postcss-preset-env": "^9.3.0",
|
||||
"postcss-url": "^10.1.3",
|
||||
"prettier": "^3.1.1",
|
||||
"prettier-plugin-go-template": "^0.0.15",
|
||||
"stylelint": "^16.0.2",
|
||||
"stylelint-prettier": "^5.0.0"
|
||||
},
|
||||
"name": "davegallant.github.io",
|
||||
"version": "0.1.0"
|
||||
}
|
149
public/404.html
@@ -1,168 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"><title>About - davegallant</title><link rel="icon" type="image/png" href=https://davegallant.ca/favicon.ico /><meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="I’m a software tinkerer with a passion for infrastructure, tooling, security, and coffee.
|
||||
Feel free to reach out at me@davegallant.ca." />
|
||||
<meta property="og:image" content=""/>
|
||||
<meta property="og:title" content="About" />
|
||||
<meta property="og:description" content="I’m a software tinkerer with a passion for infrastructure, tooling, security, and coffee.
|
||||
Feel free to reach out at me@davegallant.ca." />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:url" content="/about/" /><meta property="article:section" content="" />
|
||||
|
||||
|
||||
|
||||
<meta name="twitter:card" content="summary"/>
|
||||
<meta name="twitter:title" content="About"/>
|
||||
<meta name="twitter:description" content="I’m a software tinkerer with a passion for infrastructure, tooling, security, and coffee.
|
||||
Feel free to reach out at me@davegallant.ca."/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@1,500&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fira+Sans&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono" rel="stylesheet">
|
||||
|
||||
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="/css/main.5ff68256cc04aa4360600458bf9767c053d7b990cfb09caa0724dd24045068c7.css" />
|
||||
<link id="darkModeStyle" rel="stylesheet" type="text/css" href="/css/dark.d61dc67f7e7db9e2fb71ee6e28efc53086daed613da0bbeb0ef66045420afd17.css" disabled />
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript"
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/x-mathjax-config">
|
||||
MathJax.Hub.Config({
|
||||
tex2jax: {
|
||||
inlineMath: [['$','$'], ['\\(','\\)']],
|
||||
displayMath: [['$$','$$'], ['\[','\]']],
|
||||
processEscapes: true,
|
||||
processEnvironments: true,
|
||||
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
|
||||
TeX: { equationNumbers: { autoNumber: "AMS" },
|
||||
extensions: ["AMSmath.js", "AMSsymbols.js"] }
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.15.2/dist/katex.min.css">
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.2/dist/katex.min.js"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.2/dist/contrib/auto-render.min.js" onload="renderMathInElement(document.body);"></script>
|
||||
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
renderMathInElement(document.body, {
|
||||
delimiters: [
|
||||
{left: "$$", right: "$$", display: true},
|
||||
{left: "$", right: "$", display: false}
|
||||
]
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/custom.d96bfb9e3314a7699144ab6ae7331d424cbd7fb34a2e890b17e7bb7db4e30f3a.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="content"><header>
|
||||
<div class="main">
|
||||
<a href="/">davegallant</a>
|
||||
</div>
|
||||
<nav>
|
||||
|
||||
<a href="/">Posts</a>
|
||||
|
||||
<a href="/about">About</a>
|
||||
|
||||
<a href="/index.xml">RSS</a>
|
||||
</nav>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="https://storage.ko-fi.com/cdn/widget/Widget_2.js"
|
||||
></script>
|
||||
<span id="dark-mode-toggle" onclick="toggleTheme()"></span>
|
||||
<script src="/js/themetoggle.js"></script>
|
||||
|
||||
|
||||
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<article>
|
||||
<div class="title">
|
||||
<h1 class="title">About</h1>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<section class="body"><p>I’m a software tinkerer with a passion for infrastructure, tooling, security, and coffee.</p>
|
||||
<p>Feel free to reach out at <a href="mailto:me@davegallant.ca">me@davegallant.ca</a>.</p>
|
||||
</section>
|
||||
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="https://storage.ko-fi.com/cdn/widget/Widget_2.js"
|
||||
></script>
|
||||
<script type="text/javascript">
|
||||
kofiwidget2.init("Buy me a coffee", "#a15bc2", "F1F2S4LWI");
|
||||
kofiwidget2.draw();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="post-tags">
|
||||
|
||||
</div>
|
||||
</article>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<script src="https://storage.ko-fi.com/cdn/scripts/overlay-widget.js"></script>
|
||||
<div style="display: flex"><a class="soc" href="mailto:me@davegallant.ca" rel="me" title="Email"
|
||||
><i data-feather="at-sign"></i
|
||||
></a>
|
||||
<a class="border"></a><a class="soc" href="https://linktr.ee/davegallant" rel="me" title="LinkTree"
|
||||
><i data-feather="compass"></i
|
||||
></a>
|
||||
<a class="border"></a><a class="soc" href="https://github.com/davegallant" rel="me" title="GitHub"
|
||||
><i data-feather="github"></i
|
||||
></a>
|
||||
<a class="border"></a><a class="soc" href="https://mastodon.social/@davegallant" rel="me" title="Mastodon"
|
||||
><i data-feather="speaker"></i
|
||||
></a>
|
||||
<a class="border"></a><a class="soc" href="https://www.linkedin.com/in/dave-gallant/" rel="me" title="LinkedIn"
|
||||
><i data-feather="linkedin"></i
|
||||
></a>
|
||||
<a class="border"></a></div>
|
||||
<div class="footer-info">
|
||||
2023 Dave Gallant
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-V8WJDERTX9"></script>
|
||||
<script>
|
||||
var doNotTrack = false;
|
||||
if (!doNotTrack) {
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'G-V8WJDERTX9', { 'anonymize_ip': false });
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
feather.replace();
|
||||
</script></div>
|
||||
</body>
|
||||
</html>
|
BIN
public/android-chrome-192x192.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
public/android-chrome-512x512.png
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
public/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 7.8 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 7.4 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 7.4 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 9.4 KiB |
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 9.1 KiB |