Disk passthrough to a VM managing my ZFS array.
$ qm set 100 -scsi1 /dev/disk/by-id/…
$ qm set 100 -scsi2 /dev/disk/by-id/…
$ …
version: "3" | |
name: utils | |
x-options: &options | |
environment: &environment | |
TZ: "${TIMEZONE}" | |
restart: unless-stopped | |
networks: | |
- utils |
defmodule MyApp.RepoConnectionReaper do | |
@moduledoc """ | |
Disconnect all connections after a X minutes to reset cache build-up and leaky memory on long-lived connections | |
Especially useful for dynamic queries which contribute to this build-up. | |
Alternatively, use this Repo option e.g. `Repo.all(query, prepare: :unnamed)` to avoid using named prepared statements | |
on queries that are dynamic enough to not cache the prepared statement on the connection. | |
See also | |
- https://github.com/elixir-ecto/db_connection/issues/99 |
#!/bin/bash | |
find /dev/disk/by-id/ -type l | xargs -I{} ls -l {} | grep -v -E '[0-9]$' | sort -k11 | cut -d' ' -f9,10,11,12 |
#!/usr/bin/python | |
from slack_cleaner2 import * | |
s = SlackCleaner('TOKEN') | |
channel = "CHANNEL_NAME" | |
for msg in s.c[channel].msgs(with_replies=True): | |
if msg.user == s.myself: | |
print(f"DELETED: {msg.text}") |
// Nullable user example: | |
type MaybeUser = UserQuery['user'] | |
/** | |
* Possibly null user, such as on an auth page | |
* Here's a description on why these overloads are required: https://stackoverflow.com/a/67640634 | |
*/ | |
export function useMaybeUser<UserData = MaybeUser>( | |
select: (user: MaybeUser) => UserData |
/** | |
* environment variables: | |
* WORKING_DIRECTORY - set to absolute path such as /tmp | |
* GIT_REMOTE_{some unique number or key} - set to cloneable HTTPS repo URL such as 'https://github.com/brettinternet/homelab' | |
*/ | |
import { stat } from "node:fs/promises" | |
import { existsSync } from "node:fs" | |
import { dirname, parse as pathParse, join as pathJoin } from "node:path" | |
import { parse as urlParse, fileURLToPath } from "node:url" | |
import { promisify } from "node:util" |
const createList = (length) => | |
[...new Array(length)].map((_, index) => ({id: (index + 1).toString() })) | |
const length = 10000 | |
const items = createList(length).map(c => ({ ...c, inner: createList(length) })) | |
console.log(items) | |
const lastId = length.toString() | |
const itemId = lastId | |
const innerItemId = lastId |
const tc = | |
<T extends (...args: Parameters<T>) => ReturnType<T>>( | |
cb: T, | |
condition = true | |
): ((...args: Parameters<T>) => ReturnType<T> | undefined) => | |
(...args: Parameters<T>) => { | |
if (condition) { | |
try { | |
return cb(...args) | |
} catch (error) { |
#!/bin/bash | |
# Work from a terminal you're more comfortable in (and for scrolling) | |
set -xe | |
if passwd -S root | grep -q "NP"; then | |
echo "Set root password:" | |
passwd | |
fi |