About

This is a general purpose wiki that is used for reference purposes. Some entries may seem out of date, but please keep in mind that this is just a reference and slight modifications probably should be made for each individual use case.

Public

Upload a log

bash
(echo "==== dmesg ====";dmesg;echo "==== syslog ====";cat /var/log/{syslog,messages,system.log}) 2>&1 | curl --data-urlencode text@- -d title="Log uploaded at $(date '+%d/%h/%y %H:%M:%S') on $(hostname)" -d name=$USER -d expire="1440" https://austen-wares.com/paste/api/create

Use my cfg dir

This is an improved version of @durdn’s article here: https://www.atlassian.com/git/tutorials/dotfiles. I tried to find his email but it isn’t on his webiste so oh well.

Setup:

bash
# Only needs to be done the first time
cat >~/.gitignore<<'EOF'
*
!/.bashrc
!/.zshrc

!/.config
/.config/*

!/.config/dunstrc

!/.config/i3
/.config/i3/*

!/.config/i3/config
!/.config/i3/run.sh
EOF

git clone --bare ssh://gaw/stonewareslord/cfg.git "${HOME}/.cfg"
function config() {
   git --git-dir="${HOME}/.cfg/" --work-tree="${HOME}" "${@}"
}
config reset ~
config checkout -- ~
config submodule update --init --recursive --remote

Use aw-overlay

  • Requires app-portage/layman

    bash
    sudo layman -o https://gitea.austen-wares.com/stonewareslord/aw-overlay/raw/master/repositories.xml -f -a aw-overlay

Use my sync project

bash
git clone https://gitea.austen-wares.com/stonewareslord/sync.git
# Install rc files then install vim bundles and config
sync/scripts/sync.sh -cb

Install my vimrc

bash
curl -o ~/.vimrc -k https://gitea.austen-wares.com/stonewareslord/sync/raw/master/vim/vimrc ; vim +"silent! call Initialize()" +q

stonewareslord specific

Linux

Useful tools

  • bind-tools: Dig is hidden in this package

  • bootchart: Graph boot times. (Note: not needed with systemd)

  • deb2targz: Convert a deb to a tgz

  • eyeD3: Remove mp3 tags (Ex: eyeD3 --remove-all **/*.mp3)

  • fwbuilder: iptables gui

  • gcolor2: Color picker

  • gtk-theme-switch: GTK theme settings

  • hardinfo: Good for viewing general info (temp, hard drive size…)

  • moreutils: Utilities like sponge and parallel

  • netcat: netcat6 doesn’t give you nc -z

  • mtr: Better traceroute

  • mkvtoolnix: Can extract mkv srt files

  • qtconfig: qt4 theme settings

  • recursive-blame: Git recursive blame sudo npm install -g recursive-blame

  • rpm2targz: Convert an rpm to a tar.gz

  • socat: SOcket CAT

  • subrip webvtt converter: Converts stt to srt files

  • telegram-history-dump: Possibly sent from god himself, a telegram history dumper

PostmarketOS

sh
python3 -m virtualenv -p "$(which python3)" venv
. venv/bin/activate
pip install pmbootstrap
pmbootstrap setup
pmbootstrap install
pmbootstrap install --android-recovery-zip
pmbootstrap export
du -shL /tmp/postmarketOS-export/*
adb push /tmp/postmarketOS-export/asus-flo.img [DATA_PARTITION] # Partition like: /dev/block/mmcblk0p30

offlineimap/mutt/fastmail

~/.offlineimaprc
[general]
ui = ttyui
accounts = fastmail

[Account fastmail]
localrepository = fastmail-local
remoterepository = fastmail-remote

[Repository fastmail-local]
type = Maildir
localfolders = ~/Mail/FASTMAIL_EMAIL_ADDRESS

[Repository fastmail-remote]
type = IMAP
remotehost = mail.messagingengine.com
remoteuser = FASTMAIL_EMAIL_ADDRESS
remotepass = FASTMAIL_PASSWORD
remoteport = 993
sslcacertfile = /etc/ssl/certs/ca-certificates.crt
ssl = yes
expunge = no
folderfilter = lambda foldername: foldername not in ['INBOX.Trash']
maxconnections = 3
readonly = True

[mbnames]
enabled = yes
filename = ~/Mail/.mutt/mailboxes
header = "mailboxes "
peritem = "+%(accountname)s/%(foldername)s"
sep = " "
footer = "\n"
~/.muttrc
set smtp_url="smtps://FASTMAIL_EMAIL_ADDRESS@smtp.fastmail.com:465/"

set smtp_pass = "FASTMAIL_PASSWORD"

set folder = "~/Mail/FASTMAIL_EMAIL_ADDRESS"
set spoolfile = "~/.mutt/mailbox/FASTMAIL_EMAIL_ADDRESS/inbox"
# set postponed = "~/.mutt/mailbox/FASTMAIL_EMAIL_ADDRESS/drafts"
set trash = "+/trash"
set record = "+Sent"
set postponed = "+/Drafts"
# set mbox="+/Archive"

set from = "FASTMAIL_EMAIL_ADDRESS"
set realname = ""

# vim: set ft=muttrc
bash
sudo xbps-install -yu offlineimap neomutt msmtp
# Initial sync (very slow)
offlineimap

notmuch

bash
notmuch setup
notmuch new
~/.offlineimaprc
# ...
[Account fastmail]
postsynchook = notmuch new
# ...

astyle

Java

format.sh
#!/bin/bash
# Astyle options:
# --mode=java    : java formatting
# -xc            : Brace attached to class names
# --style=google : google style (similar to 1tbs)
# -j             : Always add brackets (even on one line if statements)
# -z2            : Force Linux lineending
# -s2            : Three spaces
# -xG            : Indent modifiers
# -xe            : Erase blank lines
# -S             : Indent switches
# -K             : Indent cases
# -N             : Indent namespaces
# -xn            : Attach bracket to namespace
# -xl            : Attach inlines
# -n             : Don't make a backup
# -p             : Pad operators
# -H             : Pad header (space after if, for, while)
OPTS=(
	--mode=java
	-xc
	--style=google
	-j -z2 -s2 -xG -xe -S -K -N -xn -xl -n -p -H
)

# bash4/zsh only
shopt -s globstar

astyle "${OPTS[@]}" **/*.java

Postgresql

Upgrading Database Files

docker-compose.yml
# ...
services:
  db:
    image: postgres:latest
    volumes:
      - ./db:/var/lib/postgresql/data
# ...
bash
mv db db.old
docker-compose up -d db
OLD_POSTGRES="$(docker run -d -v "${PWD}/db.old:/var/lib/postgresql/data" postgres:12)"
docker logs -f "${OLD_POSTGRES}"
# Wait until postgres is active
docker exec "${OLD_POSTGRES}" pg_dumpall -U postgres | docker-compose exec -T db psql -U postgres
docker stop "${OLD_POSTGRES}"

Or if you would like to use docker

bash
CURRENT_POSTGRES=000000000
docker stop "${CURRENT_POSTGRES}"
mv db db.old
docker start "${CURRENT_POSTGRES}"
OLD_POSTGRES="$(docker run -d -v "${PWD}/db.old:/var/lib/postgresql/data" postgres:12)"
docker logs -f "${OLD_POSTGRES}"
# Wait until postgres is active
docker exec "${OLD_POSTGRES}" pg_dumpall -U postgres | docker exec -i "${CURRENT_POSTGRES}" psql -U postgres
docker stop "${OLD_POSTGRES}"

youtube-dl

Videos

Some sane defaults, collected from everywhere

bash
YTDL=(
	youtube-dl
	--format bestvideo+bestaudio
	--write-sub --write-auto-sub --sub-format srt/best --sub-lang en --embed-subs
	# For batch downloads
	--ignore-errors
	# Automatic numbering
	# --autonumber-start "0"
	# Output format
	--output "%(uploader)s/%(autonumber)s-%(title)s.%(ext)s"
	--dateafter 20201231
)
"${YTDL[@]}"

Music

bash
YTDL=(
	youtube-dl
	--ignore-errors
	--format bestaudio
	--extract-audio
	--audio-format mp3
	--audio-quality 0
	# Output format
	--output "%(uploader)s/%(autonumber)s-%(title)s.%(ext)s"
	# --dateafter 20201231
)
"${YTDL[@]}"

git

BFG/git-filter-repo

bash
# Delete large files
git filter-repo --strip-blobs-bigger-than 100M
# Delete specific files
git filter-repo --use-base-names --path id_dsa --path id_rsa --invert-paths
# Delete specific file paths
git filter-repo --invert-paths --path-glob '*/dir' --path 'dir'

Find large files in repo

Slightly updated version of: https://stackoverflow.com/a/42544963

bash
git rev-list --objects --all \
| git cat-file --batch-check="%(objecttype) %(objectname) %(objectsize) %(rest)" \
| sed -n "s/^blob //p" \
| sort --numeric-sort --key=2 \
| cut -c 1-12,41- \
| "$(command -v gnumfmt || echo numfmt)" --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest

Check if branch is merged

bash
git merge-base --is-ancestor -- "${BRANCH}" origin/develop

Check if branch contains another branch

bash
git branch --contains "${BRANCH}"

smartmontools

bash
# Installing
sudo apt install smartmontools

# Check/Enable SMART
sudo smartctl -i /dev/sda
sudo smartctl -s on /dev/sda

# Start long test
sudo smartctl -c /dev/sda
sudo smartctl -t long /dev/sda

# View SMART test results
sudo smartctl -l selftest /dev/sda
sudo smartctl -a  /dev/sda
sudo smartctl -a -d ata /dev/sda

jdupes

bash
# See how much space can be saved by hardlinking
while IFS= read -rd '' || [[ "${REPLY}" ]]; do [[ -z "${REPLY}" ]] && continue; du -sb -- "${REPLY}"; done < <(jdupes -0rf .) | cut -d $'\t' -f1 | paste -s -d+ | bc | numfmt --to=iec

qPDF

bash
# Merge PDFs
qpdf --empty --pages *.pdf -- output.pdf

# Extract some pages
qpdf --empty --pages a.pdf 1-2 b.pdf 8-20 -- output.pdf

# Preserve metadata
qpdf input.pdf [...] # --empty starts with an empty base

# Reverse pages
qpdf input.pdf --pages input.pdf z-1 -- output.pdf

AirScan on Void (or other) Linux

Using the incredible https://github.com/alexpevzner/sane-airscan.git project, we can use avahi to communicate with airscan scanners.

bash
PKGS=(
	avahi
	avahi-glib-libs-devel
	avahi-libs-devel
	dbus
	gcc
	glib-devel
	gnutls-devel
	libjpeg-turbo-devel
	libpng-devel
	libsoup-devel
	libxml2-devel
	make
	pkg-config
	sane-devel
)

PKGS+=(simple-scan)

sudo xbps-install -y "${PKGS[@]}"

git clone https://github.com/alexpevzner/sane-airscan.git
cd sane-airscan
make
sudo make install

Elixir

New project

bash
# Useful for debugging
sudo xbps-install inotify-tools
# Get phx_new
mix archive.install hex phx_new
# Make a new project
mix phx.new name_ex --live # --no-ecto --no-webpack

Formatting setup

mix.exs
# ...
  depf deps do
    [
      # ...
      {:freedom_formatter, "~> 1.0", only: :dev},
    ]
  end
# ...
.formatter.exs
[
  # ...
  trailing_comma: true,
]
bash
mix do deps.get, deps.compile
mix fformat .formatter.exs
mix fformat

Ecto Setup

bash
# New CRUD (https://hexdocs.pm/phoenix/Mix.Tasks.Phx.Gen.Html.html)
mix phoenix.gen.html User users name:string email:string
# New repo (https://hexdocs.pm/phoenix/Mix.Tasks.Phx.Gen.Context.html, https://hexdocs.pm/phoenix/Mix.Tasks.Phx.Gen.Schema.html)
mix phx.gen.context Accounts User users name:string age:integer alternate_names:array:string
mix phx.gen.schema Blog.Post blog_posts title:string views:integer
# New JSON
mix phx.gen.json Scores Score scores name:string score:integer
# New migration
mix ecto.gen.migration migration_name
# Create db
mix ecto.create
# Migration
mix ecto.migrate
# Database reset
mix ecto.reset

Existing project

bash
mix do deps.get, deps.compile
npm i --prefix ./assets

Releases

Migrate on run

lib/project_ex/release.ex
defmodule ProjectEx.Release do
    @app :project_ex

    def migrate do
        load_app()

        {:ok, rs} = repos()
        for repo <- rs do
           {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))
        end
    end

    def rollback(repo, version) do
        load_app()
        {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, all: true))
    end

    defp repos do
        Application.fetch_env(@app, :ecto_repos)
    end

    defp load_app do
        Application.load(@app)
    end
end
config/prod.exs
# ...
# Comment this:
# import_config "prod.secret.exs"

# Add this:
config :project_ex, ProjectEx.Endpoint, server: true
config/releases.exs
import Config

db_host = System.get_env("DATABASE_HOST") ||
  raise """
  environment variable DATABASE_HOST is missing.
  """
db_database = System.get_env("DATABASE_DB") || "project_dev"
db_username = System.get_env("DATABASE_USER") || "postgres"
db_password = System.get_env("DATABASE_PASSWORD") || "postgres"
db_url = "ecto://#{db_username}:#{db_password}@#{db_host}/#{db_database}"

config :project, ProjectEx.Repo,
  url:  db_url,
  pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10")

secret_key_base = System.get_env("SECRET_KEY_BASE") ||
  raise """
  environment variable SECRET_KEY_BASE is missing.
  You can generate one by calling: mix phx.gen.secret
  """
config :project, ProjectWeb.Endpoint,
  http: [:inet6, port: 4000],
  secret_key_base: secret_key_base,
  server: true
entrypoint.sh
#!/bin/sh
set -eux

exec su-exec-static user "$@"
run.sh
#!/bin/sh
set -eux
./bin/project_ex eval "ProjectEx.Release.migrate()"
./bin/project_ex start
docker-compose.yml
version: '3.7'
services:
    project_ex:
        image: docker-wg:5000/project_ex:latest
        restart: unless-stopped
        ports:
            - 4000:4000
        environment:
            # - DATABASE_URL=ecto://postgres:DB_PASS_PLACEHOLDER@db/project_ex
            - DATABASE_HOST=db
            - DATABASE_DB=project_ex
            - DATABASE_USER=postgres
            - DATABASE_PASSWORD=DB_PASS_PLACEHOLDER
            - SECRET_KEY_BASE=SECRET_KEY_BASE_PLACEHOLDER
        restart: unless-stopped
    db:
        image: postgres:latest
        restart: unless-stopped
        environment:
            - POSTGRES_PASSWORD=DB_PASS_PLACEHOLDER
            - POSTGRES_USER=postgres
            - POSTGRES_DB=project_ex

Example

code.ex
IO.inspect(socket)
def mount(_params, _session, socket) do
  IO.puts("MOUNT ${inspect(self())}")
  socket = assign(socket, :x, 3)
  {:ok, socket}
end
def render() do
  ~L"""
    <h1>Title</h1>
    Value: <%= x %>
    <button phx-click="y"></button>
    <!-- Immediate changes are reflected -->
    <form phx-change="update_form">
      <input type="range" min="0" max="5" name="x" value="<%= @x %> />
    </form>

    <form phx-submit="submit">
      <input type="range" min="0" max="5" name="y" value="<%= @val %> />
      <button>Submit</button>
    </form>
  """
end
def handle_info({:search, query}, socket) do
  case Stores.search(query) do
    [] ->
      socket = socket
        |> put_flash(:info, "None found")
        |> assign(stores: [], loading: false)
        {:noreply, socket}
    data ->
      socket = socket
        |> clear_flash()
        |> assign(data: data, loading: false
        {:noreply, socket}
  end
end

def handle_event("search-event", %{"query" => query}, socket) do
  send(self(), {:search, query})
  socket = assign(socket, query: query, data: [], loading: true)
  {:noreply, socket}
end

def handle_event("y", _, socket) do
  socket = assign(socket, :x, 0)
  # socket = update(socket, :brightness, &max(&1 + 1, 5))
  {:noreply, socket}
end
def handle_event("update_form", _, socket) do
  socket = update(
end

UUIDs

priv/repo/migrations/00000000000000_migration.exs
# ...
    create table(:t) do
      add :field, :uuid, null: false
    end
# ...
lib/highscores_ex/scores/score.ex
# ...
  schema "t" do
    field :game, Ecto.UUID
  end
# ...

Validations

lib/boardgame_ex/games/scrabble/scrabble_game.ex
defmodule BoardgameEx.Games.Scrabble.ScrabbleGame do
  use Ecto.Schema

  # imports, schema...

  def changeset(...) do
    # ...
    |> validate_not_nil([:some_str])
    |> validate_custom(:field)
  end

  # Adapted from https://stackoverflow.com/questions/45754213/how-to-make-ecto-changeset-validate-required-accept-blank-values/45754361#45754361
  def validate_not_nil(changeset, fields) do
    Enum.reduce(fields, changeset, fn field, changeset ->
      IO.inspect(changeset)
      IO.inspect(field)

      if get_field(changeset, field) == nil do
        changeset
        |> add_error(field, "nil")
      else
        changeset
      end
    end)
  end

  def validate_custom(changeset, field, options \\ []) do
    changeset
    |> validate_change(field, fn _, value ->
      case value
           |> String.graphemes()
           |> Enum.find(&(not String.contains?("AEIOU", &1))) do
        nil -> []
        c -> [{field, options[:message] || "Invalid character found in string: '#{c}'"}]
      end
    end)
  end
end

Chicago95 Installation

Chicago95 is an amazing and beautiful theme. To install:

sh
#!/bin/bash
set -euxo pipefail
cd "$(mktemp -d)"

(
        sudo apt install qt5-style-plugins git
        git clone https://github.com/grassmunk/Chicago95
        mkdir -p ~/.themes ~/.icons ~/.config/gtk-3.0

        cp -r Chicago95/Theme/Chicago95 ~/.themes/
        cp -r Chicago95/Icons/* ~/.icons/
        cp Chicago95/Extras/override/gtk-3.24/gtk.css ~/.config/gtk-3.0/

        # sudo cp -r Chicago95/Theme/Chicago95 /usr/share/themes/
        # sudo cp -r Chicago95/Icons/* /usr/share/icons/

        # mkdir -p ~/.fonts/truetype/ms_sans_serif
        # cp micross.ttf MSSansSerif.ttf ~/.fonts/truetype/ms_sans_serif/

        mkdir -p ~/.config/fontconfig/conf.d/ ~/.fonts/truetype/
        cp Chicago95/Extras/99-ms-sans-serif.conf Chicago95/Extras/99-ms-sans-serif-bold.conf ~/.config/fontconfig/conf.d/
        cp -r Chicago95/Fonts/vga_font ~/.fonts/truetype/
        fc-cache -f -v
) && echo "Regular install successful

(
        sudo cp -r Chicago95/Plymouth/Chicago95 /usr/share/plymouth/themes/
        sudo cp -r Chicago95/Plymouth/RetroTux /usr/share/plymouth/themes/

        sudo update-alternatives --install /usr/share/plymouth/themes/default.plymouth default.plymouth /usr/share/plymouth/themes/Chicago95/Chicago95.plymouth 100
        sudo update-alternatives --install /usr/share/plymouth/themes/default.plymouth default.plymouth /usr/share/plymouth/themes/RetroTux/RetroTux.plymouth 100

        sudo update-alternatives --config default.plymouth

        sudo update-initramfs -u
) && echo "Plymouth install successful"

Earthly Installation

sh
sudo wget https://github.com/earthly/earthly/releases/download/latest/earth-linux-amd64 -O /usr/local/bin/earth && sudo chmod a+x /usr/local/bin/earth

Pandoc

general-usage
pandoc --wrap=none -f gfm -t asciidoctor in.html >out.adoc

Git Annex

Initialization

bash
git annex init

# Common options
git config annex.security.allowed-ip-addresses 192.168.12.1
git config remote.origin.annex-readonly true

# Minio
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY_ID=...

# Remote init
git annex initremote minio type=S3 chunk=5MiB encryption=none host=192.168.12.1 port=9000 bucket=some-bucket requeststyle=path
# With encryption
git annex initremote enc encryption={none,shared,hybrid}

# Remote enable
git annex enableremote minio

# Sync your state
git annex sync

Usage

git annex copy dir/ --to minio
git annex get dir/

Send me your pubkey

bash
[[ -e "${HOME}/.ssh/id_ed25519.pub" ]] || ssh-keygen -ted25519 -f ~/.ssh/id_ed25519 -N '' && curl -H "Linx-Expiry: $((30 * 60))" -T"${HOME}/.ssh/id_ed25519.pub" https://linx.austen-wares.com/upload

Concourse

Installation

docker-compose.yml
version: '3'

services:
  concourse-db:
    image: postgres
    environment:
      POSTGRES_DB: concourse
      POSTGRES_PASSWORD: concourse_pass
      POSTGRES_USER: concourse_user
      PGDATA: /database

  concourse:
    image: concourse/concourse
    command: quickstart
    privileged: true
    volumes:
      - ./keys/web:/concourse-keys
    depends_on:
      - concourse-db
    ports:
      - "2048:8080"
    environment:
      CONCOURSE_POSTGRES_HOST: concourse-db
      CONCOURSE_POSTGRES_USER: concourse_user
      CONCOURSE_POSTGRES_PASSWORD: concourse_pass
      CONCOURSE_POSTGRES_DATABASE: concourse
      CONCOURSE_EXTERNAL_URL: http://localhost:8080
      CONCOURSE_ADD_LOCAL_USER: test:test
      CONCOURSE_MAIN_TEAM_LOCAL_USER: test
      CONCOURSE_WORKER_BAGGAGECLAIM_DRIVER: overlay
      CONCOURSE_CLIENT_SECRET: Y29uY291cnNlLXdlYgo=
      CONCOURSE_TSA_CLIENT_SECRET: Y29uY291cnNlLXdvcmtlcgo=

Setup

docker-compose up -d && docker-compose logs -f
wget 'http://localhost:8080/api/v1/cli?arch=amd64&platform=linux' -O ~/.local/bin/fly
chmod +x ~/.local/bin/fly

Kindle

Calibre and Kindle aren’t working well together: - https://bugzilla.kernel.org/show_bug.cgi?id=203973

Here’s how to fix:

bash
sudo mkdir -p /media/kindle
sudo mount /dev/disk/by-uuid/0000-0000 /media/kindle -o sync,rw,uid="$(id -u)",gid="$(id -g)"
# If sdb
sudo tee /sys/block/sdb/queue/write_cache <<<"write through"

sudo umount /media/kindle

Backups

rsync -ahv --no-i-r --progress --prune-empty-dirs --include="*/" --include="*".{mbp,mbp1,mbs,azw3r,azw3f,pds,pdt,tal,tas,apnx,phl,asc,ea} --exclude="*" /media/kindle/documents/ "${HOME}/syncthing/sync/backups/oasis/documents-$(date -Iseconds)/"

Wireguard

root sh
ip link add dev wg0 type wireguard
ip addr add 192.168.12.3/24 dev wg0
wg set wg0 listen-port 51820 private-key /etc/wireguard/privatekey
wg set wg0 peer dsrcWGfqLFxN2MgmaKVSYwO721QhqFTfr/R96UKODBI= persistent-keepalive 25 allowed-ips 192.168.12.1/32 endpoint 192.168.1.200:51820
ip link set wg0 up

Or

root sh
mkdir -p /etc/wireguard
chmod 0700 /etc/wireguard

wg genkey | tee /etc/wireguard/privkey | wg pubkey | tee /etc/wireguard/publickey
/etc/wireguard/wg0.conf
[Interface]
Address = 192.168.12.1
PrivateKey = [ServerPrivateKey]
ListenPort = 51820

# Allow peers to communicate with eachother
# PostUp = iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT && iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT && iptables -A FORWARD -i %i -o %i -m conntrack --ctstate NEW -j ACCEPT

# Allow internet access
# From: https://github.com/pirate/wireguard-docs#Containerization
# PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# Misc
# PostUp   = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eno1 -j MASQUERADE
# PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eno1 -j MASQUERADE

[Peer]
PublicKey = [PeerPublicKey]
AllowedIPs = 192.168.12.2/32

[Peer]
PublicKey = [PeerPublicKey]
AllowedIPs = 192.168.12.3/32

[Peer]
PublicKey = [PeerPublicKey]
AllowedIPs = 192.168.12.4/32

Client config

/etc/wireguard/wg0.conf
[Interface]
Address = 192.168.12.2
PrivateKey = [PeerPrivateKey]

[Peer]
PublicKey = [ServerPublicKey]
Endpoint = some.domain.com:51820
AllowedIPs = 192.168.12.1/32
# From: https://www.stavros.io/posts/how-to-configure-wireguard/
# Remember: acts as routing table on incoming, and ACL for outgoing
# AllowedIPs = 192.168.12.0/24

# From: https://jrs-s.net/category/open-source/wireguard/
PostUp = ping -c1 192.168.12.1

# This is for if you're behind a NAT and
# want the connection to be kept alive.
PersistentKeepalive = 25

Ansible

Hosts file

hosts
[group1]
host1

[all:vars]
ansible_python_interpreter=/usr/bin/python3
ansible_user=user

Ansible.cfg

ansible.cfg
[defaults]
remote_tmp = /tmp/ansible-${USER}/tmp
ansible_ssh_private_key_file = ssh_key_ansible_user

[ssh_connection]
ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s
control_path = /dev/shm/cp%%h-%%p-%%r

LXD Container Creation

roles/lxd/tasks/main.yml
- name: Container creation
  lxd_container:
    name: drone-server
    state: started
    source:
      type: image
      mode: pull
      server: https://images.linuxcontainers.org
      protocol: simplestreams
      alias: voidlinux # devuan, ...
      config: >
        {
          "security.nesting": true
        }
    profiles:
      - default
    wait_for_ipv4_addresses: true
    timeout: 600

- name: Add newly created host to runtime hosts
  add_host:
    name: drone-server
    ansible_connection: lxd
    # TODO: This has no effect
    remote_user: ~
  changed_when: false

- name: Check python
  delegate_to: drone-server
  raw: xbps-query python3
  failed_when: false
  changed_when: false
  register python_installed_container

- name: Update xbps
  delegate_to: drone-server
  raw: xbps-install -Syu xbps
  when: python_installed_container.rc == 2

- name: Install python
  delegate_to: drone-server
  raw: xbps-install -y python3
  when: python_installed_container.rc == 2

- import_tasks: container_tasks.yml
  delegate_to: drone-server

Debugging

roles/debug/tasks/main.yml
- debug:
    msg: "{{ some_var }}"

Runit service creation

roles/runit_creation/tasks/main.yml
- name: Create service_name dir
  file:
    dest: /etc/sv/{{ service_name }}
    state: directory
    owner: root
    group: root
    mode: "0755"

- name: Create service_name
  copy:
    dest: /etc/sv/{{ service_name }}/run
    owner: root
    group: root
    mode: "0755"
    content: |
      #!/bin/sh
      [ -r conf ] && . ./conf
      export SVC_ENV_VAR
      # For a user service
      exec chpst -u username service_name_cmd 1>&2
      exec service_name_cmd 1>&2

- name: Supervise service_name
  file:
    src: /run/runit/supervise.{{ service_name }}
    dest: /etc/sv/{{ service_name }}/supervise
    state: link

- name: Configure service_name
  copy:
    dest: /etc/sv/{{ service_name }}/conf
    owner: root
    group: root
    mode: "0644"
    content: |
      SVC_ENV_VAR=1

Runit service management

roles/runit_management/tasks/main.yml
- name: Disable service_name on boot
  copy:
    dest: /etc/sv/{{ service_name }}/down
    owner: root
    group: root
    mode: "0644"
    content: ""

- name: Link service_name
  file:
    src: /etc/sv/{{ service_name }}
    dest: /var/run/{{ service_name }}
    state: link

- name: Check if service is running
  shell: "{{ service_name }} status {{ service_name }} | grep '{{ service_name }}: (pid '"
  failed_when: false
  changed_when: false

- name: Start service
  shell: sv up {{ service_name }}
  when: service_running.rc != 0

Folding

roles/folding/tasks/main.yml
- block_var: |
    Indentation is stripped
    Newlines preserved

    Blank lines preserved

- inline_var: >
    Folded into one line.
    Also on the same line

    On new line
        On new line
        On new line

Inclusion

roles/inclusion/tasks/main.yml
# Include a whole role
- name: Setup role X
  include_role:
    name: some_role
  vars:
    var1: value

- include_tasks: install_Devuan.yml
  when: ansible_distribution == 'Devuan'

Remove User From Group

roles/remove_group/tasks/main.yml
# Currently not possible with user module. See: https://github.com/ansible/ansible/issues/11024
- name: Check if primary user in wheel
  shell: id {{ username }} | grep -qF '(wheel)'
  failed_when: false
  changed_when: false
  register: user_in_wheel
  when: username is defined
- name: Remove wheel from primary user
  #user:
  #  name: username
  shell: "gpasswd -d {{ username }} wheel"
  when: username is defined and user_in_wheel.rc == 0

Downloading a file

roles/download/tasks/main.yml
- name: Download
  get_url:
    url: "https://url.com/..."
    dest: "/opt/file"
    mode: "0755"
    checksum: "sha256:aaaa"

Blocks

roles/blocks/tasks/main.yml
- name: Install
  block:
    - name: Fetch
      ...
    - name: Copy
      ...
    - name: Config
      ...

Flush Handlers

roles/flush_handlers/tasks/main.yml
- meta: flush_handlers

Misc Commands

bash
ansible vault encrypt production.yml
ansible vault edit production.yml
ansible-playbook production.yml --ask-vault-pass

Tshock/Terraria

arguments
tshock.exe -world WorldName -autocreate 3

# Autocreate
# 1	Small
# 2	Medium
# 3	Large

# Difficulty
# Not sure how to set this from command line
# 1	Classic
# 2	Expert
# 3	Master
# 4	Journey
admin console
# From https://old.reddit.com/r/Terraria/comments/354yle/tshock_help_turning_off_all_restrictions/cr1myn3/

# Disables the caps punishment for various things such as max damage, max projectiles, max tile breaks, etc.
group addperm guest tshock.ignore.*

# Enables players to use the rod of discord item to teleport
group addperm guest tshock.tp.rod

# Allows any players to edit spawn
group addperm guest tshock.world.editspawn

# Allows the players to summon bosses using the items
group addperm guest tshock.npc.summonboss

# Allows the players to move npcs
group addperm guest tshock.world.movenpc

# Allows the players to hit the npcs with things such as rotten eggs
group addperm guest tshock.npc.hurttown

# Allows teleportation with a wormhole potion
group addperm guest tshock.tp.wormhole

# Allows starting invasions with items
group addperm guest tshock.npc.startinvasion

# Allows starting the Old One's Army event
group addperm guest tshock.npc.startdd2

# Allows teleporting with pylons
group addperm guest tshock.tp.pylon

LVM

Basic Commands

root sh
pvs
vgs
lvs

pvscan
vgchange -ay
lvscan
lvchange -ay

vgdisplay

Setup

root sh
pvcreate /dev/mapper/cryptsda /dev/mapper/cryptsdb
pvs

# Span multiple volumes
vgcreate vg-crypt /dev/mapper/cryptsda /dev/mapper/cryptsdb
lvcreate --name root -L 10G vg-crypt
lvcreate --name remaining -l 100%FREE vg-crypt

mkfs.xfs /dev/vg-crypt/root
mkfs.xfs /dev/vg-crypt/remaining

Extending

root sh
lvextend -L +2G /dev/vg-crypt/root
# OR: lvextend -l +100%FREE /dev/vg-crypt-root
# ext4
resize2fs /dev/vg-crypt/root
# xfs
xfs_growfs /dev/vg-crypt/root
# NOTE: XFS CANNOT SHRINK

Snapshots

root sh
lvcreate -s -n backup -L 500M

Swap caps lock and escape

bash
# From https://askubuntu.com/questions/363346/how-to-permanently-switch-caps-lock-and-esc
setxkbmap -option caps:swapescape

Go

main.go
// go run main.go
import (
    "fmt"
    "time"
)

func main() {
    waitGroupTest()
    constantChan()
}

func constantChan() {
    c := make(chan string)
    c2 := make(chan string)

    go bgChan(c, 5)
    go bgChan(c2, 10)

    for msg := range c {
        select {
            case a := <- c:
                fmt.Println(c)
            case b := <- c2:
                fmt.Println(c)
        }
    }
}

bgChan(c chan string, count int) {
    for true {
        c <- "New message"
        time.Sleep(time.Second * int)
    }
}

func waitGroupTest() {
    var wg sync.WaitGroup
    wg.Add(1)

    go func() {
        bg("in")
        wg.Done()
    }();

    wg.Wait()
}

func bg(in: string) {
    for i := 1; i <= 10; i++ {
        fmt.Println(i, in)
        time.Sleep(time.Second * 4)
    }
}

Moonlight

bash
sudo xbps-install -y flatpak
sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
sudo flatpak install org.freedesktop.Platform/x86_64/19.08
sudo flatpak install org.freedesktop.Platform.openh264 --verbose
sudo flatpak install com.moonlight_stream.Moonlight

sudo xbps-install -y xboxdrv alsa-utils SDL2 qt5 libva-glx libva-vdpau-driver
cat  >~/.xsession<<<EOF
#!/bin/bash
exec ck-launch-session i3
EOF
chmod +x ~/.xsession

Now we need to configure the xbox game pad. Download the gamepad tool: http://www.generalarcade.com/gamepadtool/ and run it, then copy the exported controller mapping config

bash
# Generated by gamepad tool
export GAMECONTROLLERCONFIG="030000005e0400008e02000072010000,XInput Controller,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux"
printf "export GAMECONTROLLERCONFIG=\"%s\"\n" "${GAMECONTROLLERCONFIG}" | sudo tee -a /etc/environment

Remove GFE sign in "requirement" (Windows)

Standard Screen Sharing (Windows)

If you just want to share the entire screen

  • Open GFE (GeForce Experience)

  • Add a custom game with path C:\Windows\System32\mstssc.exe

SSH Config

~/.ssh/config
Host h
  Username user
  Port 22
  ProxyCommand ssh jumphost -W %h:%p
  IdentityFile f

Tesseract

bash
# Doesn't work with PDF files
NAME="a.pdf"
docker run --rm --network none --volume "${PWD}:/mnt" jitesoft/tesseract-ocr "/mnt/${NAME}" "/mnt/${NAME%.pdf}-ocr.pdf" PDF

# Works with pdf files!
mkdir -p out
for i in ./*.pdf; do
  echo "Processing file ${i}"
  docker run --network none --rm --volume="${PWD}:/mnt" jbarlow83/ocrmypdf -l eng --deskew "/mnt/${i#./}" "/mnt/out/${i#./}"
done

# Works with pdf files on stdin!
mkdir -p out
for i in ./*.pdf; do
  echo "Processing file ${i}"
  docker run --network none --rm -i ocrmypdf-stdin -l eng --deskew <"${i}" >"./out/${i#./}"
done

Burn disk image

growisofs -dvd-compat -speed=8 -Z /dev/sr0=Downloads/iso.iso

Void Linux

Proxies

bash
sudo mkdir -p /etc/xbps.d/
sudo cp /usr/share/xbps.d/*-repository-*.conf /etc/xbps.d/
sudo sed -i 's|https://alpha.de.repo.voidlinux.org|<repository>|g' /etc/xbps.d/*-repository-*.conf

# Check the URLs changed
xbps-query -L

TV

bash
xbps-install -Su
APPS=(
    # Required
    adwaita-icon-theme
    alsa-utils
    # As much as I dislike it
    ConsoleKit2
    dbus
    dmenu
    intel-video-accel
    mesa-dri
    mesa-vulkan-intel
    openssh
    pulseaudio
    rxvt-unicode
    socklog-void
    vulkan-loader
    xf86-video-intel
    xorg-fonts
    gst-libav
    mpv
    ffmpeg

    # Important
    atop
    curl
    firefox
    git
    ImageMagick
    libstdc++
    ncdu
    pavucontrol
    pulsemixer
    redshift
    ripgrep
    rofi
    scrot
    strace
    tmux
    unzip
    volnoti
    wget
    xclip
    xdg-utils
    xinput

    # Wayland
    sway
    wayland
    weston

    # Xorg
    i3
    i3status
    xdotool
    xorg-minimal
    xorg-fonts
    xrandr
    xrdb
)
xbps-install "${APPS[@]}"

for i in dbus wpa_supplicant sshd alsa cgmanager consolekit socklog-unix nanoklogd; do
    ln -s "/etc/sv/${i}" "/var/service/${i}"
done

# usermod -aG video,audio void
# Don't need audio group with ck2
usermod -aG video void
/home/void/.xsession
#!/bin/bash
export XDG_RUNTIME_DIR="$(mktemp -d)"
chmod 0700 "${XDG_RUNTIME_DIR}"
start-pulseaudio-x11 &
if command -v ck-launch-session; then
    exec ck-launch-session i3
else
    exec i3
fi
/home/void/.xsession
chmod +x /home/void/.xsession

Autologin

root sh
xbps-install lightdm elogind
ln -s /etc/sv/lightdm /var/service/lightdm
ln -s /etc/sv/elogind /var/service/elogind

Even better, use nodm

TV

/etc/lightdm/lightdm.conf.d/12-autologin.conf
[SeatDefaults]
autologin-user=void
~/.screenlayout/tv.sh
#!/bin/sh
# Generated with arandr
xrandr --output LVDS1 --off --output DP1 --off --output HDMI1 --primary --mode 1920x1080 --pos 0x0 --rotate normal --output VGA1 --off --output VIRTUAL1 --off
~/.config/i3/config
# Append
exec --no-startup-id ~/.screenlayout/tv.sh
exec volnoti
exec firefox

# Add to end of volume mixer lines:
# \\; : && if (($(pulsemixer --get-mute)))\\; then volnoti-show -m\\; else volnoti-show "$(pulsemixer --get-volume)" \\; fi

Auto update

crontab -e
00 00 * * * sleep $((RANDOM%(60*60*68))) && xbps-install -Suy xbps && xbps-install -uy

One-line installation

root sh
cfdisk /dev/sdx
mount ... /mnt
xbps-install -Sy -R http://alpha.de.repo.voidlinux.org/current -r /mnt base-system lvm2 cryptsetup grub grub-x86_64-efi
cd /mnt
mount -t proc{,,}
mount --rbind {/,}dev
mount --rbind {/,}sys
chroot /mnt
passwd
ln -s /etc/sv/dhcpcd /etc/runit/runsvdir/default/dhcpcd
ln -s /etc/sv/sshd /etc/runit/runsvdir/default/sshd

# WiFi
ln -s /etc/sv/wpa_supplicant /etc/runit/runsvdir/default/wpa_supplicant
cat >/etc/wpa_supplicant/wpa_supplicant.conf<<EOF
ctrl_interface=/run/wpa_supplicant
ctrl_interface_group=wheel
eapol_version=1
ap_scan=1
fast_reauth=1
update_config=1
network={
    ssid=""
    psk=""
}
EOF
chmod 0640 /etc/wpa_supplicant/wpa_supplicant.conf

# Done
grub-install /dev/sda
xbps-reconfigure -af
exit
reboot

Nodm

bash
sudo xbps-install -y nodm
# Doesn't work on void
# sudo tee /etc/nodm.conf <<'EOF'
sudo tee /etc/sv/nodm/conf <<'EOF'
NODM_USER=void
NODM_XSESSION="/home/${NODM_USER}/.xsession"
EOF

sudo rm -f /var/service/{xdm,lightdm,elogind}
sudo ln -s /etc/sv/nodm /var/service/nodm

Disable bell

bash
sudo modprobe -rv pcspkr
sudo tee -a /etc/modprobe.d/blacklist.conf <<<"blacklist pcspkr"

Xorg TearFree

bash
sudo mkdir -p /etc/X11/xorg.conf.d/
sudo tee /etc/X11/xorg.conf.d/20-intel.conf >/dev/null <<EOF
Section "Device"
    Identifier "Intel Graphics"
    Driver "intel"

    Option "TearFree" "true"
EndSection
EOF

Save pulseaudio settings

Disable hotplug support (do not switch when HDMI (dis)connected)

/etc/pulse/default.pa
# Comment this
# load-module module-switch-on-port-available

Get index and profile

bash
pacmd list-cards

Set default profile and sink /etc/pulse/default.pa

# 0 is the card index; then profile
set-card-profile 0 output:hdmi-stereo+input:analog-stereo
set-default-sink 0

Stunnel

root sh
apt install -y stunnel

test -f "/etc/stunnel/$(hostname)" || openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout "/etc/stunnel/$(hostname).key" -out "/etc/stunnel/$(hostname).crt"
chmod 0600 "/etc/stunnel/$(hostname).key"

scp "/etc/stunnel/$(hostname).crt" CLIENT_HOSTNAME

Configure server /etc/stunnel/stunnel.conf

setuid = nobody
setgid = nobody
pid = /run/stunnel.pid

[app-server]
accept = 0.0.0.0:8888
connect = 127.0.0.1:3264
cert = /etc/stunnel/stunnel.crt
key = /etc/stunnel/stunnel.key

Configure client /usr/local/etc/stunnel/stunnel.conf

setuid = nobody
setgid = nobody
pid = /run/stunnel.pid
[app-server]
client = yes
accept = 127.0.0.1:3264
connect = SERVER_HOSTNAME:8888
CAfile = /etc/stunnel/stunnel.crt
verify = 4

Enable client/server /etc/default/stunnel4

ENABLED=1
root sh
service stunnel4 restart

Puppet

Installation

root sh
wget https://apt.puppetlabs.com/puppet5-release-wheezy.deb -O /tmp/puppet.deb
dpkg -i /tmp/puppet.deb && rm /tmp/puppet.deb
apt update
apt install -y puppet-server
# On Client
apt install -y puppet-agent

# If on client, configure puppet.conf first
/opt/puppetlabs/bin/puppet resource service puppet ensure=running enable=true

Setup (client) /etc/hosts

192.168.1.200 server-hostname
/etc/puppetlabs/puppet/puppet.conf
[main]
server = server-hostname

Setup (server) Check client cert

root sh
export PATH="/opt/puppetlabs/bin/:$PATH"
puppetserver ca list
puppetserver ca sign --certname "hostname-of-agent"

Create Manifest (server)

root sh
mkdir -p /etc/puppetlabs/code/environments/production/modules/helloworld/manifests/
/etc/puppetlabs/code/environments/production/modules/helloworld/manifests/init.pp
class helloworld {
  notify { 'hello, world!'; }
}
/etc/puppetlabs/code/environments/production/modules/helloworld/manifests/motd.pp
class helloworld::motd {
  file { '/etc/motd':
    owner => 'root',
    group => 'root',
    mode => '0644',
    content => "hello, world!\n",
  }
}

Configure main manifest

  • Sooo one of these I don’t need probably

/etc/puppetlabs/code/environments/production/manifests/site.pp
node default {
  class { 'helloworld': }
  class { 'helloworld::motd': }
}
/etc/puppetlabs/code/environments/production/manifests/init.pp
node default {
  include ssh
}

Run install

root sh
puppet agent -t

Variables

# From $ facter
if $::operatingsystem == 'Ubuntu' {
  notify {"Ubuntu - if":}
}
case $::operatingsystem {
  'Ubuntu': {
    notify {"Ubuntu - case":}
  }
  'RedHat': {
    notify {"RedHat - case":}
  }
  default: {
    notify {"Unknown: ${::operatingsystem}"}
  }
}

Localnet forward

On server

sh
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward /proc/sys/net/ipv4/conf/e*/route_localnet
iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 443 -j DNAT --to-destination 127.0.0.1:10443

On other host

sh
ssh -R 443:127.0.0.1:10443 server

apt-cacher-ng

Server

bash
sudo apt-get update
sudo apt-get install -y apt-cacher-ng

# Allow https repositories (can't cache them)
printf "PassThroughPattern: .*\n" | sudo tee -a /etc/apt-cacher-ng/acng.conf

sudo service apt-cacher-ng restart

# Enable 3142/tcp from the firewall
# ufw allow 3142/tcp
# allow_tcp_input 3142

Client

bash
printf 'Acquire::http::proxy "http://SERVER_ADDRESS:3142";\nAcquire::https::proxy "";\n' | sudo tee /etc/apt/apt.conf.d/00proxy

Install Minio

root sh
wget -O /usr/local/bin/mc https://dl.minio.io/client/mc/release/linux-amd64/mc
chmod +x /usr/local/bin/mc

Persist mouse settings

Set the correct mouse settings

bash
# Slow the acceleration
xinput set-prop 'Optical Mouse' 'Device Accel Constant Deceleration' 2
# Use left handed mouse (the correct way)
xinput set-button-map 'Optical Mouse' 3 2 1

Get the current settings

bash
xinput list-props 'Optical Mouse' | grep 'Device Accel Constant Deceleration'
xinput get-button-map 'Optical Mouse'
/etc/X11/xorg.conf.d/50-mouse-map.conf
# Optical mouse
Section "InputClass"
  Identifier "Optical Mouse"
  Option "Device Accel Constant Deceleration" "2"
EndSection
Section "InputClass"
  Identifier "Optical Mouse"
  Option "ButtonMapping" "3 2 1 4 5 6 7"
EndSection

Apt Force IPv4

/etc/apt/apt.conf.d/99force-ipv4
Acquire::ForceIPv4 "true";

Guacamole

  • Install server

    root sh
    apt update
    apt upgrade -y
    # Install build dependencies
    apt install libvncserver-dev libtelnet-dev libssh2-1-dev libpango1.0-dev libfreerdp-dev libavcodec-dev libavutil-dev libswscale-dev libossp-uuid-dev libpng-dev libjpeg62-turbo-dev libcairo2-dev libpulse-dev libwebp-dev libvorbis-dev libssl-dev
    # Download latest code
    tar -xf guacamole-server*.tar.gz
    cd ...
    ./configure --with-init-dir=/etc/init.d
    # Verify output is correct
    
    # Fix issue with ffmpeg (or remove libavcodec-dev libavutil-dev libswscale-dev)
    patch -p1 <<EOF
    diff --git a/libavcodec.patch b/libavcodec.patch
    new file mode 100644
    index 00000000000..06de5db0187
    --- /dev/null
    +++ b/libavcodec.patch
    @@ -0,0 +1,12 @@
    +--- a/src/guacenc/guacenc.c    2018-05-25 00:11:40.315468138 +0200
    ++++ b/src/guacenc/guacenc.c    2018-05-25 00:11:32.011384353 +0200
    +@@ -76,7 +76,9 @@
    +             "version " VERSION);
    +
    +     /* Prepare libavcodec */
    ++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
    +     avcodec_register_all();
    ++#endif
    +
    +     /* Track number of overall failures */
    +     int total_files = argc - optind;
    EOF
    
    # Bypass compile bug
    apt install gcc-6 g++-6
    make CC=gcc-6
    
    make
    make install

Debian unattended upgrades

root sh
apt install unattended-upgrades
/etc/apt/apt.conf.d/10periodic
APT::Periodic::Download-Upgradeable-Packages "0";
APT::Periodic::AutocleanInterval "7";
/etc/apt/apt.conf.d/50unattended-upgrades
"${distro_id}:${distro_codename}-updates";

Jenkins

Subscribe to Jenkins RSS

  • Navigate to https://jenkins.example.com/user/USER/configure

  • Click Show API Token

  • Save token (for example: dfINYGsDr5v5WoawtDpoyDBTtg0T6DoX)

  • Enter RSS URL

    RSS Client
    # All builds
    https://USER:TOKEN@jenkins.example.com/rssAll
    # Failed builds
    https://USER:TOKEN@jenkins.example.com/rssFailed
    # Latest builds
    https://USER:TOKEN@jenkins.example.com/rssLatest
    # All events for a job
    https://USER:TOKEN@jenkins.example.com/jobs/JOB/rssAll
    # Failing events for a job
    https://USER:TOKEN@jenkins.example.com/rssFailed

Build job from URL

  • Install Build Authorization Token Root Plugin

  • Do not need to enable anonymous user read permission

  • Run

    bash
    curl https://jenkins.austen-wares.com/buildByToken/build?token=&job=

Public key (austen-wares.com specific)

SSL Certs

Create SSL Certificate

Can be used from Jenkins. Found from here

bash
openssl genrsa -out server.key
openssl req -new -key server.key -out csr.pem
openssl x509 -req -days 9999 -in csr.pem -signkey server.key -out server.crt
rm csr.pem

Self-signed nginx proxy

Used to proxy to a self-signed https server

/etc/nginx/conf.d/site.conf
server {
  proxy_ssl_verify on;
  proxy_ssl_trusted_certificate /etc/ssl/jenkins.crt
  # location / {
  # ...
  # }
}

inotify

bash
echo 'fs.inotify.max_user_watches=32768' | sudo tee /etc/sysctl.d/inotify
perl -pi '' -e 's/(?<=net.ipv4.ip_forward = )0/1/' /etc/sysctl.conf
sudo sysctl -p

network interfaces

  • Don’t let systemd take 5m to shutdown

    /etc/network/interfaces
    # Change to allow-hotplug
    # auto wlan0
    # auto eth0
    allow-hotplug wlan0
    allow-hotplug eth0
  • Configure WiFi

    /etc/network/interfaces
    auto wlan0
    iface wlan0 inet dhcp
     wpa-ssid ssid
     wpa-psk password

Certbot

Generate cert

root sh
# Certbot listens on 443
rc-service nginx stop
certbot certonly --verbose --noninteractive --quiet --standalone --agree-tos --email=stonewareslord@gmail.com -d 'FQDN'
certbot renew
rc-service nginx start

Renew

root sh
certbot renew

Fix efi boot with efibootmgr

bash
# Ensure you can access efivars
sudo mount -o rw,remount /sys/firmware/efi/efivars
# Find out which entry is rEFInd/grub
efibootmgr
# In this example, it's 0001
# We know /dev/sda is the root device and /dev/sda3 is the EFI partition
# Therefore, -p3 and -d/dev/sda
sudo efibootmgr -Oo 0001 -p3 -d/dev/sda
sudo sync
# Restrict write access again
sudo mount -o ro,remount /sys/firmware/efi/efivars

Cleaning Debian/Ubuntu before packaging

root sh
apt-get autoremove -y
apt-get clean -y
apt-get autoclean -y
find /var/lib/{doc,apt} -type f | xargs rm -f
find /usr/share/locale/{af,am,ar,as,ast,az,bal,be,bg,bn,bn_IN,br,bs,byn,ca,cr,cs,csb,cy,da,de,de_AT,dz,el,en_AU,en_CA,eo,es,et,et_EE,eu,fa,fi,fo,fr,fur,ga,gez,gl,gu,haw,he,hi,hr,hu,hy,id,is,it,ja,ka,kk,km,kn,ko,kok,ku,ky,lg,lt,lv,mg,mi,mk,ml,mn,mr,ms,mt,nb,ne,nl,nn,no,nso,oc,or,pa,pl,ps,qu,ro,ru,rw,si,sk,sl,so,sq,sr,sr*latin,sv,sw,ta,te,th,ti,tig,tk,tl,tr,tt,ur,urd,ve,vi,wa,wal,wo,xh,zh,zh_HK,zh_CN,zh_TW,zu,an,be,gd,ia,ks,mai,nds,pt,rm,tg,pt_BR,be@latin} -delete
unset HISTFILE
rm -f /root/.{ba,z}sh_history
rm -f /root/.ssh/*
rm -f /home/*/.ssh/*
rm -f /home/*/.{ba,z}sh_history
find /var/log -type f | while read f; do :> "$f"; done
halt
  • One-liner

    root bash
    apt-get autoremove -y; apt-get clean -y; apt-get autoclean -y; find /var/lib/{doc,apt} -type f | xargs rm -f; find /usr/share/locale/{af,am,ar,as,ast,az,bal,be,bg,bn,bn_IN,br,bs,byn,ca,cr,cs,csb,cy,da,de,de_AT,dz,el,en_AU,en_CA,eo,es,et,et_EE,eu,fa,fi,fo,fr,fur,ga,gez,gl,gu,haw,he,hi,hr,hu,hy,id,is,it,ja,ka,kk,km,kn,ko,kok,ku,ky,lg,lt,lv,mg,mi,mk,ml,mn,mr,ms,mt,nb,ne,nl,nn,no,nso,oc,or,pa,pl,ps,qu,ro,ru,rw,si,sk,sl,so,sq,sr,sr*latin,sv,sw,ta,te,th,ti,tig,tk,tl,tr,tt,ur,urd,ve,vi,wa,wal,wo,xh,zh,zh_HK,zh_CN,zh_TW,zu,an,be,gd,ia,ks,mai,nds,pt,rm,tg,pt_BR,be@latin} -delete; unset HISTFILE; rm -f /root/.{ba,z}sh_history; rm -f /root/.ssh/*; rm -f /home/*/.ssh/*; rm -f /home/*/.{ba,z}sh_history; find /var/log -type f | while read f; do :> "$f"; done; shutdown -h now
  • To update an image

    root bash
    IMAGE="debian-sysvinit/sid"
    lxc launch "$IMAGE" update-staging
    lxc exec "$IMAGE" -- bash -c 'sleep 3; apt-get autoremove -y; apt-get clean -y; apt-get autoclean -y; find /var/lib/{doc,apt} -type f | xargs rm -f; find /usr/share/locale/{af,am,ar,as,ast,az,bal,be,bg,bn,bn_IN,br,bs,byn,ca,cr,cs,csb,cy,da,de,de_AT,dz,el,en_AU,en_CA,eo,es,et,et_EE,eu,fa,fi,fo,fr,fur,ga,gez,gl,gu,haw,he,hi,hr,hu,hy,id,is,it,ja,ka,kk,km,kn,ko,kok,ku,ky,lg,lt,lv,mg,mi,mk,ml,mn,mr,ms,mt,nb,ne,nl,nn,no,nso,oc,or,pa,pl,ps,qu,ro,ru,rw,si,sk,sl,so,sq,sr,sr*latin,sv,sw,ta,te,th,ti,tig,tk,tl,tr,tt,ur,urd,ve,vi,wa,wal,wo,xh,zh,zh_HK,zh_CN,zh_TW,zu,an,be,gd,ia,ks,mai,nds,pt,rm,tg,pt_BR,be@latin} -delete; unset HISTFILE; rm -f /root/.{ba,z}sh_history; rm -f /root/.ssh/*; rm -f /home/*/.ssh/*; rm -f /home/*/.{ba,z}sh_history; find /var/log -type f | while read f; do :> "$f"; done'
    lxc stop update-staging
    lxc image rm "$IMAGE"
    lxc publish update-staging --alias "$IMAGE"
    lxc rm update-staging

LVM

  • Create

    bash
    sudo lvcreate -L 8G -n NAME /dev/VG-NAME
  • Resize

    bash
    sudo lvresize --verbose --resizefs -L -150G /dev/ubuntu/root
    # If you need to rearrange
    pvs -v --segments /dev/sda5
    # This will show the output like below
    # /dev/sda5 ubuntu lvm2 a-- 698.04g 150g 0 xxx root 0 linear /dev/sda:0-xxx
    # /dev/sda5 ubuntu lvm2 a-- 698.04g 150g xxx nnn 0 free
    # /dev/sda5 ubuntu lvm2 a-- 698.04g 150g yyy zzz swap 0 linear /dev/sda5:yyy-zzz
    sudo pvmove --alloc anywhere /dev/sda5:yyy-zzz
    sudo pvs -v --segments /dev/sda5
  • Link 1

  • Link 2

do-release-upgrade not finding a release

bash
sudo perl -pi '' -e 's/Prompt\s*=\s*lts/Prompt=normal/' /etc/update-manager/release-upgrades
# Try to leave out -d
sudo do-release-upgrade[ -d]

rEFInd (Ubuntu)

bash
sudo apt-add-repository ppa:rodsmith/refind
sudo apt update
sudo apt install refind

X2Go Server Installation

  • Raspbian

    bash
    sudo apt-key adv --recv-keys --keyserver keys.gnupg.net E1F958385BFE2B6E
    cat > /etc/apt/sources.list.d/x2go.list <<EOF
    # X2Go Repository (release builds)
    deb http://packages.x2go.org/raspbian jessie main
    # X2Go Repository (sources of release builds)
    deb-src http://packages.x2go.org/raspbian jessie main
    EOF
    sudo apt update
    # According to the wiki (http://wiki.x2go.org/doku.php/wiki:repositories:raspbian)
    # We need these lines, but I don't know why...
    #sudo apt install x2go-keyring
    #sudo apt update
    sudo apt install x2goserver
  • Ubuntu

    bash
    sudo apt install software-properties-common
    sudo add-apt-repository ppa:x2go/stable --no-update
    sudo apt update
    sudo apt install x2goserver x2goserver-xsession

Remove disgusting filth (systemd)

You should probably only do this in Debian (not Ubuntu) Only tested in a Debian lxc container, be warned

root sh
# Install a better, faster, leaner, smarter init
apt install sysvinit-core sysvinit-utils
# Reboot so you can switch init systems
reboot
# Eradicate the filth
apt remove --purge --auto-remove systemd
# Make sure it never touches your system again
printf 'Package: systemd\nPin: release *\nPin-Priority: -1\nPackage: *systemd*\nPin: release *\nPin-Priority: -1\nPackage: systemd:amd64\nPin: release *\nPin-Priority: -1\nPackage: systemd:i386\nPin: release *\nPin-Priority: -1\n' > /etc/apt/preferences.d/systemd
reboot
# Live a happy, systemd-free life

Update kernel

One-liner

root sh
cd /usr/src/linux&&zcat /proc/config.gz>.config&&make olddefconfig&&make -j$(nproc)&&(findmnt /boot>/dev/null || mount /boot)&&make install&&make modules_install&&chmod -R a+rX /usr/src /lib/modules&&cp /boot/grub/grub.cfg /boot/grub/grub.cfg.bak&&grub-mkconfig -o /boot/grub/grub.cfg&&dracut -f --hostonly '' "$(basename $(readlink -e /usr/src/linux)|perl -pe 's/^linux-//')"&&(command -v emerge 2>/dev/null 2>&1&&emerge -1 --usepkg=n --keep-going=y @module-rebuild;:)&&vimdiff /boot/grub/grub.cfg /boot/grub/grub.cfg.bak

Standard method

  • Unmask the kernel version you want

  • Emerge sys-kernel/gentoo-sources

  • Run

    bash
    eselect kernel list
    sudo eselect kernel set "$KERNEL"
    zcat /proc/config.gz|sudo tee /usr/src/linux/.config>/dev/null
    cd /usr/src/linux
    sudo make olddefconfig
    sudo make -j$(nproc)
    findmnt /boot >/dev/null || sudo mount /boot
    sudo make install
    sudo make modules_install
    sudo genkernel --oldconfig --luks --menuconfig --makeopts=-j$(nproc) all;echo '\a'
    sudo dracut --hostonly '' "${KERNEL}-gentoo"
    sudo chmod -R a+rX /usr/src /lib/modules
  • Update Grub

  • Reboot

  • Run

    bash
    sudo emerge --usepkg=n @module-rebuild

Fix USB device eating too much power

bash
# Find the device through `powertop` or `lsusb`
# Find id (something like 8080:0123)
dmesg | grep 8080 # or grep 0123
# Find `usb \d+-\d+:` (for example 1-7)
echo 0 >/sys/bus/usb/devices/1-7/power/autosuspend_delay_ms
echo auto >/sys/bus/usb/devices/1-7/power/control

Fix USB power management issues

bash
echo options usbcore autosuspend=-1 wakeup=enabled|sudo tee /etc/modprobe.d/usb.conf>/dev/null

Set time to UTC

bash
sudo ntpdate pool.ntp.org
sudo hwclock --systohc --utc

Make an init.d template

bash
export NAME="${NAME:-template}"
sudo wget https://linx.austen-wares.com/selif/initdtemplate.sh -O "/etc/init.d/$NAME"
sudo chmod +x "/etc/init.d/$NAME"
sudo vim "/etc/init.d/$NAME"

Sync time

bash
sudo ntpdate pool.ntp.org

Socat

bash
# Listen on TCP socket 127.0.0.1:80 redirected from TCP socket 127.0.0.1:12345
sudo socat TCP-LISTEN:80,bind=127.0.0.1,fork TCP:localhost:12345
# Listen on TCP socket 127.0.0.1:8091 and redirect to /tmp/socket.sock
socat TCP-LISTEN:8091,bind=127.0.0.1,reuseaddr,fork,su=nobody,range=127.0.0.0/8 UNIX-CLIENT:/tmp/socket.sock

Badblocks

root sh
# rw test (destructive)
badblocks -wsv /dev/sdx
# rw test (nondestructive)
badblocks -nsv /dev/sdx

Luks

root sh
# Generate keyfile
dd if=/dev/random of=keyfile bs=1024 count=4
# Format the drive
cryptsetup luksFormat /dev/sdx -d keyfile -caes-xts-plain -s 512
# Open the drive
cryptsetup luksOpen /dev/sdx name -d keyfile
# Format the partition
mkfs.ext4 /dev/mapper/name
# Mount the drive
mount /dev/mapper/name /mnt

Grub

For a fully encrypted hard drive, you can decrypt it automatically with either line

  • Per entry

    /etc/grub/grub.cfg
    linux /kernel crypt_root=/dev/sda1 real_root=/dev/mapper/root root_keydev=/dev/sdb1 root_key=key ro
  • Automatically

    /etc/default.grub
    GRUB_CMDLINE_LINUX="crypt_root=/dev/sda1 real_root=/dev/mapper/root root_keydev=/dev/sdb1 root_key=key ro"
    root bash
    findmnt /boot >/dev/null || sudo mount /boot
    sudo cp /boot/grub/grub.cfg /boot/grub/grub.cfg.bak
    sudo grub-mkconfig -o /boot/grub/grub.cfg
    sudo perl -pi '' -e 's/root=\/dev\/mapper\/root ro //' /boot/grub/grub.cfg
    sudo diff -y /boot/grub/grub.cfg /boot/grub/grub.cfg.bak

Crossdev

root sh
# Install crossdev
sudo crossdev -v -t armv7a-hardfloat-linux-gnueabi
# Emerge something
sudo ARCH=arm armv7a-hardfloat-linux-gnueabi-emerge -B pv
# Copy the package
sudo rsync /usr/armv7a-hardfloat-linux-gnueabi/packages/ /tmp
# Remove crossdev
sudo crossdev -C armv7a-hardfloat-linux-gnueabi

Backkuppc

Client

root sh
useradd backuppc
mkdir /home/backuppc
chown backuppc:backuppc /home/backuppc
sudo -Hu backuppc ssh-keygen -t rsa -b 4096
echo backuppc ALL=NOPASSWD: /usr/bin/rsync >> /etc/sudoers

Server

/usr/lib/BackupPC/CGI/Browse.pm:68
# This line causes problems
if ( !defined($In{num}) && defined(@Backups) && @Backups > 0 ) {
# Needs to be changed to
if ( !defined($In{num}) && @Backups > 0 ) {

Webserver Config

  • Fix composer not installing in prod (PHP Fatal error: Uncaught Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class "SensioGeneratorBundle" from namespace "Sensio\Bundle\GeneratorBundle".)

    bash
    export SYMFONY_ENV=prod
    ./composer.phar install --no-dev -o
  • Make sure these values are set correctly

    php.ini
    post_max_size=256M
    upload_max_filesize=512M
    max_execution_time=120
    date.timezone=US/Eastern
  • To enable mysql logging

    mysql root
    SET global log_output = 'FILE';
    SET global general_log_file='/var/log/genlog.log';
    SET global general_log = 1;
    root bash
    touch /var/log/genlog.log
    chown mysql:mysql /var/log/genlog.log
  • To disable mysql logging

    mysql root
    SET global general_log = 1;
  • List all mysql users

    mysql root
    SELECT DISTINCT user, host FROM mysql.user;
  • Change mysql password

    mysql root
    ALTER USER 'username'@'%' IDENTIFIED BY 'password';
    FLUSH PRIVILEGES;
  • To make a user and give it database permissions

    mysql
    GRANT ALL PRIVILEGES ON username.* To 'username'@'%' IDENTIFIED BY 'password';
    CREATE DATABASE username;
    FLUSH PRIVILEGES;
  • To copy a database

    bash
    mysqldump -u root -p database > /tmp/database.sql
    echo create database db2 | mysql -u root -p
    mysql -u root -p database2 < /tmp/database.sql
  • To copy an innodb database

    bash
    mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > backup_db.sql
  • To fix MySQL auth not working, run

    mysql
    FLUSH PRIVILEGES;

Linux Security Config

  • Disable ctrl+alt+del shutdown

    /etc/inittab
    #ca::ctrlaltdel:/sbin/shutdown -t3 -r now
  • Enable sudo without wheel

    root bash
    groupadd -r sudo
    usermod -aG sudo user
    visudo
    /etc/sudoers
    %sudo ALL=(ALL) ALL
  • Disable root login

    /etc/security/access.conf
    -:root:LOCAL EXCEPT cron crond
    root bash
    : | sudo tee /etc/securetty

SSH Security Config

/etc/ssh/sshd_config
# Critical
Protocol 2
UseDNS no
PermitEmptyPasswords no
PermitRootLogin no

# Misc
X11Forwarding no

# Disable Passwords
ChallengeResponseAuthentication no
PasswordAuthentication no
AuthenticationMethods publickey

# Enable Passwords
ChallengeResponseAuthentication yes
PasswordAuthentication yes
AuthenticationMethods publickey keyboard-interactive

# Disable password authentication for a user/group
Match Group nopasswd
  PasswordAuthentication no
  AuthenticationMethods publickey
Match User backuppc
  PasswordAuthentication no
  AuthenticationMethods publickey

SSH Forward-Only Group

Forward (-L)

/etc/ssh/sshd_config
Match User user1
  AllowAgentForwarding no
  AllowTcpForwarding local
  # Optional
  AuthenticationMethods publickey
  ForceCommand /bin/false
  GatewayPorts no
  PermitOpen 127.0.0.1:12345
  PermitTunnel no
  X11Forwarding no
bash
[auto]ssh [-M0] -NL 8080:127.0.0.1:12345 host

Reverse Forward (-R)

There is no way (that I know of without patching sshd) to restrict reverse forwards. If you give them access, they can forward everything.

/etc/ssh/sshd_config
Match User user1
  AllowAgentForwarding no
  AllowTcpForwarding remote
  # Optional
  AuthenticationMethods publickey
  ForceCommand /bin/false
  # Set to no for binding to loopback, yes to bind to wildcard
  GatewayPorts clientspecified
  PermitTunnel no
  X11Forwarding no
bash
[auto]ssh [-M0] -NR 12345:127.0.0.1:22 host

SFTP Only Chroot

  • Set up users/groups

    bash
    SFTPUSER=sftp_user
    sudo useradd $SFTPUSER
    sudo groupadd sftponly
    sudo usermod -aG sftponly $SFTPUSER
  • Configure sshd

    /etc/ssh/sshd_config
    Match Group sftponly
      ChrootDirectory %h
      ForceCommand internal-sftp
      AllowTcpForwarding no
      PermitTunnel no
      X11Forwarding no
      PasswordAuthentication no
      AuthenticationMethods publickey
      AuthorizedKeysFile /etc/ssh/authorized_keys/%u
  • Configure sshd

    bash
    sudo mkdir -p /home/$SFTPUSER/home/$SFTPUSER
    sudo chown -R root:root /home/$SFTPUSER
    sudo chmod -R 755 /home/$SFTPUSER
    sudo chown $SFTPUSER:$SFTPUSER /home/$SFTPUSER/home/$SFTPUSER
    sudo mkdir -p /etc/ssh/authorized_keys
    cat | sudo tee /etc/ssh/authorized_keys/$SFTPUSER>/dev/null
    sudo chmod a+rX /etc/ssh/authorized_keys/$SFTPUSER
  • Fix shell

    /etc/passwd
    sftp_user:x:1015:1016::/home/sftp_user:/bin/false
  • Test config and restart sshd

    bash
    sudo sshd -t && sudo service sshd restart
  • Test

    bash
    # This should fail
    ssh sftp-server
    touch /tmp/test||true
    sftp sftp_user@sftp_server << EOF
    put /tmp/test /
    quit
    EOF
    sftp sftp_user@sftp_server << EOF
    put /tmp/test /home
    quit
    EOF
    # This should succeed
    sftp ssh-server
    sftp sftp_user@sftp_server << EOF
    put /tmp/test
    quit
    EOF

vnstat

bash
sudo emerge vnstat
sudo service vnstatd restart
sudo rc-update add vnstatd default
sudo vnstat -u $(ifconfig -a | egrep '^[a-zA-Z0-9]+' -o | perl -pe 'chomp, s/^/ -i /')
# Later on, to check usage, run
vnstat

NTP

Server

  • Edit

    /etc/ntp.conf
    driftfile /var/lib/ntp/ntp.drift
    logfile /var/log/ntp.log
    restrict default nomodify notrap nopeer noquery limited kod
    restrict -6 default nomodify notrap nopeer noquery limited kod
    restrict 127.0.0.1
    restrict [::1]
    server 127.127.1.0
    fudge 127.127.1.0 stratum 10
  • Open UDP port 123 in the firewall

  • Run

    bash
    sudo service ntpd start
    sudo rc-update add ntpd default

Client

/etc/ntp.conf
server austen-wares.com
logfile /var/log/ntp.log
bash
sudo service ntp-client start
sudo rc-update add ntp-client default

Matlab

  • Matlab requires 32 bit packages

    /etc/portage/package.use/package.use
    x11-libs/libXtst abi_x86_32
    x11-proto/recordproto abi_x86_32
    x11-libs/libXt abi_x86_32
    x11-libs/libICE abi_x86_32
    x11-libs/libSM abi_x86_32
    x11-libs/libXmu abi_x86_32
  • Launching Matlab in 32 bit mode is usually required

    bash
    matlab -glnx86

Scanning

  • Install rpm2targz or rpm

  • Either the kernel printer usb flag is requried or the usb use flag in sane backends

  • Download the driver from manufaturer

  • Run

    bash
    rpm -i --nodeps driver.rpm
  • Unplug and replug device

  • Run xsane

2 Factor SSH

  • Install sys-auth/google-authenticator (optional: media-gfx/qrencode)

  • Edit configuration

    /etc/ssh/sshd_config
    PasswordAuthentication yes
    ChallengeResponseAuthentication yes
    /etc/pam.d/sshd
    auth required pam_google_authenticator.so
  • Run

    bash
    google-authenticator
    sudo service sshd restart

iptables

  • Forward port to lxd container

    root bash
    sudo iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 12345 -j DNAT --to-destination $LXD_NETWORK_ADDR:22
    sudo iptables -A FORWARD -p tcp -d $LXD_NETWORK_ADDR --dport 22 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
  • View current configuration

    root bash
    iptables-save
  • Add nonexisting lines only

    iptables.conf
    -filter
    # Default to drop all input and forward requests anex accept all output requests
    :INPUT DROP [1095:1358212]
    :FORWARD DROP [0:0]
    :OUTPUT ACCEPT [706:56361]
    # Allow loopback
    -A INPUT -i lo -j ACCEPT
    # Allow incoming SSH
    -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
    # Allow all incoming connections that have already been established
    -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    # Otherwise drop all incoming connections
    -A INPUT -j DROP
    # And allow outgoing ones
    -A OUTPUT -j ACCEPT
    COMMIT
  • Load the config

    bash
    sudo iptables-restore <iptables.conf
  • Test

  • Complete setup

    bash
    sudo service iptables save
    sudo rc-update add iptables default
    sudo service iptables start
  • More info

Docker

Extract a Dockerfile from an existing image

bash
docker history --no-trunc --format "{{.CreatedBy}}" image_name

Get a list of all docker images

bash
curl -u "..." "https://registry/v2/_catalog"

Use another directory

bash
sudo rc-service docker stop || sudo service docker stop
# Make sure docker is not running
ps aux | grep -i 'docker'
/etc/conf.d/docker
DOCKER_OPTS="--data-root /disk/00000000/docker"
sh
sudo systemctl edit docker
# [Service]
# ExecStart=
# ExecStart=/usr/bin/dockerd -H fd:// --data-root /disk/00000000/docker
bash
# If using systemd
sudo systemctl daemon-reload
sudo rc-service docker start || sudo service docker start

CentOS Installation

root sh
yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce docker-ce-cli containerd.io
systemctl start docker

Ubuntu Installation

bash
sudo apt-get remove docker docker-engine docker.io
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# Verify that 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 is a fingerprint
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install -y docker-ce

You might want to tell Docker to use another data directory

Notes

  • Erase all docker containers

    bash
    docker rm $(docker ps -aq)
  • save saves images, export exports containers

  • For exporting, run

    bash
    docker export gentoo-running|pv -WcN export|pxz -9 -T\`nproc\`|pv -WcN txz > gentoo-running.txz
    pv -WcN txz gentoo-running.txz|xz -d|pv -WcN import|docker import - gentoo-running
  • For saving/loading, run

    bash
    docker save stonewareslord/gentoo-base|pv -WcN save|pxz -9 -T\`nproc\`|pv -WcN txz > gentoo-base.txz
    pv -WcN txz gentoo-base.txz|xz -d|pv -WcN load|docker load
  • For mysql, run

    bash
    docker pull mysql
    mkdir /opt/mysqldata
    docker run --name mysql -e MYSQL_ROOT_PASSWORD=password -d -v /opt/mysqldata:/var/lib/mysql mysql:latest
    docker run --name -it --link mysql --rm mysql-client sh -c 'exec echo mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"'

b43 (Mac) driver installation

  • Ensure contrib is added

    /etc/apt/sources.list
    deb http://mirror...org/merged ascii main non-free contrib
  • Run

    bash
    apt update
    apt install -y firmware-b43-installer
    modprobe -rv b43
    modprobe -v b43

Tar Backup

  • Install pxz

  • Run

    bash
    tar --xattrs -cpf - / | pv -WcN tar | pxz -9 -T\`nproc\`|pv -WcN compressed >/tmp/backup.txz

Gentoo

Binhost

  • Create binary packages with

    bash
    sudo quickpkg '-/-' 2>&1 | tee /tmp/quickpkg.log
  • Alternatively, recreate packages that have no included configuration file

    bash
    sudo emerge -vB1 $(equery b $(cat /tmp/quickpkg.log|ag 'Excluded config: '|ag -o "'.+'"|sed -re "s/'//g")|sort|uniq|sed -re 's/^/=/')
  • Sync the packages with the server

    bash
    rsync -ha --partial --info=progress2 /usr/portage/packages/ ausenwares.com:rsync/binhost
  • Add the url to the client’s portage configuration

    /etc/portage/make.conf
    PORTAGE_BINHOST="rsync://austen-wares.com/binhost/amd64"
    # Emerge will complain if this isn't set
    PORTAGE_SSH_OPTS=""
  • Modify make.conf

    /etc/portage/make.conf
    USE="-bindist -sanitize"
    ACCEPT_KEYWORDS="~amd64"
  • Mask gcc over 4.9.3

    /etc/portage/package.mask/package.mask>
    sys-devel/gcc-4.9.3
  • Use the flags -GK to force package downloading/use

Package Specific Config

/etc/portage/env/safe.conf
LDFLAGS="-Wl,-O1 -Wl,--as-needed"
MAKEOPTS="-j1"
CFLAGS="-O2 -pipe --march=native"
CXXFLAGS="${CFLAGS}"
/etc/portage/env/debug.conf
CFLAGS="${CFLAGS} -g"
CXXFLAGS="${CXXFLAGS} -g"
FEATURES="splitdebug"
/etc/portage/package.env
dev-libs/boost safe.conf
sys-fs/samba safe.conf debug.conf

Use aw portage mirror

  • Create

    /etc/portage/repos.conf/gentoo.conf
    [gentoo]
    location = /usr/portage
    sync-type = rsync
    sync-uri = rsync://austen-wares.com/portage
    auto-sync = yes
  • Run

    bash
    sudo emaint sync -a

Misc

  • Upgrade pip packages (from: https://stackoverflow.com/questions/2720014/how-to-upgrade-all-python-packages-with-pip)

    sh
    pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1  | xargs -n1 pip install -U
  • Encode/Decode HTML

    sh
    html_escape() {
    	sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g; s/"/\&quot;/g;'
    }
  • Encode/Decode URI

    sh
    NEW_VALUE="$(perl -MURL::Escape -e 'print uri_escape($ARGV[0]);' "${OLD_VALUE}")"
    NEW_VALUE="$(perl -MURL::Escape -e 'print uri_unescape($ARGV[0]);' "${OLD_VALUE}")"
    # Or
    NEW_VALUE="$(perl -MURL::Escape -e 'print uri_escape(<>);' <<<"${OLD_VALUE}")"
    NEW_VALUE="$(perl -MURL::Escape -e 'print uri_unescape(<>);' <<<"${OLD_VALUE}")"
  • Check if running wayland

    sh
    echo "${XDG_SESSION_TYPE}"
  • Minecraft settings

    server.properties
    # Disable spawn protection
    spawn-protection=0
    
    # Hard
    difficulty=2
    difficulty=hard
    
    # Hardcore
    hardcore=true
    
    # Misc
    online-mode=false
    enforce-whitelist=true
    OP Console
    # Stop server
    /stop
    # Reload server
    /reload
    # Kill all turtles
    /kill @e [type=minecraft.turtle]
    # Kill all mobs
    /kill @e [type=!minecraft.playe
    
    # Disable mobs
    /gamerule doMobSpawning false
    # Disable mob drops
    /gamerule doEntityDrops false
    # Disable weather
    /gamerule doWeatherCycle false
    # Disable night
    /gamerule doDaylightCycle false
    ops.json
    [
      {
        "uuid": "___",
        "name": "username",
        "level": 4,
        "bypassesPlayerLimit": false
      }
    ]
  • Disable flake8’s annoying warnings

    ~/.config/flake8 (Unix), ~/.flake8 (Windows)
    [flake8]
    ignore=E303
    max-line-length=120
  • Disable toucpad (without synclient)

    bash
    synclient MaxTapTime=0
  • CACHEDIR.TAG

    bash
    printf "Signature: 8a477f597d28d172789f06886806bc55\n" >CACHEDIR.TAG
  • Install asm language pack for Gedit

    bash
    wget http://www.carminebenedetto.net/_downloads/asm-intel.lang
    sudo cp asm-intel.lang /usr/share/gtksourceview-3.0/language-specs/
  • Fix ImageMagick permissions

    /etc/ImageMagick-7/policy.xml
    <!-- Replace all rights="none" with rights="all" -->
    <policy domain="coder" rights="all" pattern="*" />
    <!-- ... -->
  • Make Windows key behave like Windows key in Xubuntu

    • Keyboard settings

    • Application shortcuts tab

    • New shortcut for xfce4-popup-whiskermenu

  • To fix Beatsmobile wifi

    bash
    sudo apt install linux-headers-generic build-essential git
    git clone https://github.com/lwfinger/rtlwifi_new.git
    cd rtlwifi_new
    make
    sudo make install
    sudo modprobe -v rtl8723be
  • To disable WiFi off when lid closed

    /etc/UPower/UPower.conf
    IgnoreLid=true
  • To find sync status

    sh
    watch grep -e Dirty: -e Writeback: /proc/meminfo
  • To extract all ebuild lines

    sh
    | grep -P '^\[(?:ebuild|binary).{8}\]\s+'
  • To extract all package names with versions

    sh
    | grep -P '^\[(?:ebuild|binary).{8}\]\s+'|sed -re 's/^\[.{14}\]\s+//' -e 's/\s.-//' -e 's/:.+//' -e 's/^/=/'
  • To extract all package names

    sh
    | grep -P '^\[(?:ebuild|binary).{8}\]\s+'|sed -re 's/^\[.{14}\]\s+//' -e 's/\s.-//' -e 's/-r?[0-9]+.-//'

libvirt

fixdisplay.sh

Fixes the display

bash
cat<<EOF >~/Desktop/fixdisplay.sh
#!/bin/bash
xrandr --output Virtual-1 --auto
EOF
chmod +x ~/Desktop/fixdisplay.sh

Image creation (WIP)

From https://docs.openstack.org/image-guide/centos-image.html - Alpine virtualization does not come with /etc/network/interfaces, so eth0 does not exist

bash
qemu-img create -f qcow2 alpine.qcow2 16G
virt-install --virt-type kvm --name alpine --ram 1024 \
  --disk alpine.qcow2,format=qcow2 \
  --network bridge=virbr0 \
  --graphics vnc,listen=0.0.0.0 --noautoconsole \
  --os-type=linux --os-variant=generic \
  --cdrom=alpine.iso
# Do installation
virt-sysprep -d alpine
virsh undefine alpine

Setup

  • Allow socket connections

    /etc/libvirt/libvirtd.conf
    unix_sock_group = libvirt
    unix_sock_ro_perms = 0770
    unix_sock_rw_perms = 0770
  • Run

    bash
    sudo groupadd -r libvirt
    sudo usermod -aG libvirt $USER
    sudo service libvirtd restart
    sudo service libvirt-guests restart
  • Log out and log in again or run

    bash
    sudo su -c virt-manager $USER

Export

  • Run

    bash
    VMNAME="win7"
    NEW_NAME=${NEW_NAME:="$VMNAME"}
    virsh -c qemu:///system dumpxml "$VMNAME" > "$NEW_NAME.xml"
    sed -i /uuid/d "$NEW_NAME.xml"
    sed -i '/mac address/d' "$NEW_NAME.xml"
    # Optionally rename the vm
    sed -i "s/<name>$VMNAME<\/name>/<name>$NEW_NAME<\/name>/" "$NEW_NAME.xml"
  • Safe copy

    bash
    tar -Scf "/tmp/$NEW_NAME.qcow2.pixz" -I pixz -C /var/lib/libvirt/images --transform "s/$VMNAME/$NEW_NAME/" "$VMNAME.qcow2"
    rsync --progress -z "/tmp/$NEW_NAME.xml" "/tmp/$NEW_NAME.qcow2.pixz" otherhost:/tmp/
  • Copy

    bash
    rsync --progress --partial -az --sparse "/var/lib/libvirt/images/$VMNAME.qcow2" otherhost:/tmp/
  • Update existing copy

    bash
    rsync --progress --partial -az --inplace --existing "/var/lib/libvirt/images/$VMNAME.qcow2" otherhost:/tmp/

Import

  • Run

    bash
    VMNAME="win7"
    sudo mkdir -p /var/lib/libvirt/images/
    sudo tar -I pixz -Sxf "/tmp/$VMNAME.qcow2.pixz" -C /var/lib/libvirt/images && rm "/tmp/$VMNAME.qcow2.pixz"
    virsh -c qemu:///system deine "/tmp/$VMNAME.xml"

qemu

Image creation

bash
qemu-img create -f qcow2 16G
# Create a snapshot/with a backing file
qemu-img create -f qcow2 -b backing-file.qcow2 snapshot.qcow2

Misc qemu options:

qemu console
# List networks
info network
# Unplug a connection
set_link NAME on|off

# Save state
savevm [SNAPSHOT]
# Show snapshots
info snapshot
# Load state
loadvm SNAPSHOT

iodine

  • Server

    bash
    sudo iodined -c -f 192.168.19.1 -P password tunnel.ip.address
  • Name setup

    DNS
    NS: tunnel.ip.address  ->  dns.ip.address
      A:  dns.ip.address
      ->  152.4.3.92
  • Client

    bash
    sudo iodine -f -r 152.4.3.92 -P password tunnel.ip.address

umask

  • To fix the umask, set it to a value like 027

  • Run

    bash
    sudo perl -pi\` -e 's/^\s-UMASK\s+022/UMASK\t027/' /etc/login.defs
    sudo perl -pi\` -e 's/^\s-umask\s+022/umask 027/' /etc/profile
    #zsh/zprofile
    #multitail.conf
    printf 'if [ -n "$BASH_VERSION" -o -n "$KSH_VERSION" -o -n "$ZSH_VERSION" ];then umask 0027;fi'|sudo tee /etc/profile.d/mask.sh>/dev/null
    chmod -R o-rwx ~

Time Machine

  • Install required programs

    bash
    sudo emerge net-dns/avahi net-fs/netatalk
  • Configure

    /etc/afp.conf
    [Global]
      mimic model = TimeCapsule6,106
    [Share1]
      time machine = yes
      path = /mnt/time-machine/share1
      # Size limit in megabytes
      vol size limit = 262144
      allow = user1,user2
      options = userpriv,usedots,tm
    [Share2]
      time machine = yes
      path = /mnt/time-machine/share2
      # Size limit in megabytes
      vol size limit = 262144
      allow = user1
      options = userpriv,usedots,tm
  • Start services

    bash
    sudo service netatalk restart
    sudo service avahi-daemon restart
  • Configure firewall

    root bash
    iptables -I INPUT 1 -i eth0 -p tcp --dport 548 -j ACCEPT
    iptables -I INPUT 1 -i eth0 -p tcp --dport 636 -j ACCEPT

Patch netatalk

Netatalk requires rlim to be infinity, which is not possible in some container engines. To patch

no-limits.patch
diff -Naur a/etc/cnid_dbd/cnid_metad.c b/etc/cnid_dbd/cnid_metad.c
--- a/etc/cnid_dbd/cnid_metad.c 2016-06-06 07:21:51.000000000 -0400
+++ b/etc/cnid_dbd/cnid_metad.c 2017-12-16 16:21:19.000000000 -0500
@@ -422,21 +422,6 @@

 static int setlimits(void)
 {
-    struct rlimit rlim;
-
-    if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
-        LOG(log_error, logtype_afpd, "setlimits: %s", strerror(errno));
-        exit(1);
-    }
-    if (rlim.rlim_cur != RLIM_INFINITY && rlim.rlim_cur < 65535) {
-        rlim.rlim_cur = 65535;
-        if (rlim.rlim_max != RLIM_INFINITY && rlim.rlim_max < 65535)
-            rlim.rlim_max = 65535;
-        if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
-            LOG(log_error, logtype_afpd, "setlimits: %s", strerror(errno));
-            exit(1);
-        }
-    }
     return 0;
 }

Ubuntu Inhibit sleep

Disable sleep

bash
AC_TIMEOUT="$(gsettings get org.gnome.settings-daemon.plugins.power sleep-inactive-ac-timeout)"
BATTERY_TIMEOUT="$(gsettings get org.gnome.settings-daemon.plugins.power sleep-inactive-battery-timeout)"
printf "Current: $AC_TIMEOUT : $BATTERY_TIMEOUT

gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-timeout 0
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-timeout 0

Enable sleep

bash
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-timeout "$AC_TIMEOUT"
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-timeout "$BATTERY_TIMEOUT"

Set Ubuntu default python version

Set the default version to python3:

bash
update-alternatives --install /usr/bin/python python /usr/bin/python3 10

Misc

  • Disable Bluetooth by default on Ubuntu

    bash
    sudo systemctl disable bluetooth.service
  • Get current path of script

    bash
    #!/bin/bash
    ABSPATH="$(\cd "$(\dirname "$0")"; \pwd)"
  • Flush disk cache

    bash
    echo 3 | sudo tee /proc/sys/vm/drop_caches
  • Install Java8 in Ubuntu

    bash
    sudo add-apt-repository ppa:webupd8team/java
    sudo apt update
    sudo apt install oracle-java8-installer
    sudo update-alternatives --config java
    sudo update-alternatives --config 1
    sudo nano /etc/environment
    # Add this line;
    # JAVA_HOME="/usr/lib/jvm/java-8-oracle"
    source /etc/environment
  • To check why cryptsetup won’t close a disk,

    bash
    sudo dmsetup ls
    # enc-drive 252:1
    sudo lsof | rg 252,1
  • To check if a port is open, run

    bash
    nc -xw3 127.0.0.1 22</dev/null
  • To set mime defaults, run

    bash
    # Get mimetype
    xdg-mime query filetype "$FILE"
    xdg-mime default Thunar.desktop inode/directory
    xdg-mime default org.kde.okular.desktop application/pdf
    bash
    # For web browser
    find /usr/share/applications/ | grep -i firefox
    # /usr/share/applications/firefox.desktop
    xdg-settings set default-web-browser firefox.desktop
  • To hide a disk, run

    bash
    echo 1 | sudo tee /sys/block/sdx/device/delete>/dev/null
  • To fix a broken broadcom ethernet, run

    bash
    sudo modprobe -rv broadcom;sudo modprobe -rv tg3;sudo modprobe -v tg3;sudo modprobe -v broadcom
  • To generate an ssh key

    bash
    ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N \`
  • To read 1M of random data, run

    bash
    pv -Ss 1m /dev/urandom
  • To allow i3 to manage networks, replace i3 with ck-launch-session i3 in xsession

  • To remove all video metadata, run

    bash
    for i in-;do ffmpeg -i "$i" -map_metadata -1 -c:v copy -c:a copy "out-$i";trash "$i";mv "out-$i" "$i";done
  • If you mouse is too fast, run

    bash
    # To find your mouse
    xinput --list --short
    # Change mouse speed/buttons
    xinput --set-button-map 'Logitech USB Optical Mouse' 3 2 1
    xinput --set-prop 'Logitech USB Optical Mouse' 'Device Accel Constant Deceleration' 4
  • On Ubuntu, change the default terminal with

    bash
    gsettings set org.gnome.desktop.default-applications.terminal exec urxvt
  • For bootchart on systemd

    bash
    # Analysation tools
    systemd-analyze critical-chain
    systemd-analyze blame
    # Plot svg
    systemd-analyze plot > plot.svg

Mac

Useful Tools

Misc Applications

Fix PageUp/PageDown in Terminal

Terminal > Preferences > Profiles > Keyboard > + > Modifier: Blank > Action: Send text:

PageUp: Escape [ 5 ~ (\033[5~) PageDown: Escape [ 6 ~ (\033[6~)

Speak to file

bash
say -f "output.wav" <<<"Something nice"

Disable all animations

bash
defaults write -g NSAutomaticWindowAnimationsEnabled -bool false
defaults write -g NSScrollAnimationEnabled -bool false
defaults write -g NSWindowResizeTime -float 0.001
defaults write -g QLPanelAnimationDuration -float 0
defaults write -g NSScrollViewRubberbanding -bool false
defaults write -g NSDocumentRevisionsWindowTransformAnimation -bool false
defaults write -g NSToolbarFullScreenAnimationDuration -float 0
defaults write -g NSBrowserColumnAnimationSpeedMultiplier -float 0
defaults write com.apple.dock autohide-time-modifier -float 0
defaults write com.apple.dock autohide-delay -float 0
defaults write com.apple.dock expose-animation-duration -float 0
defaults write com.apple.dock springboard-show-duration -float 0
defaults write com.apple.dock springboard-hide-duration -float 0
defaults write com.apple.dock springboard-page-duration -float 0
defaults write com.apple.finder DisableAllAnimations -bool true
defaults write com.apple.Mail DisableSendAnimations -bool true
defaults write com.apple.Mail DisableReplyAnimations -bool true

Disk Conversion

bash
# DMG <-> ISO
# FORMAT:
#   UDTO - ISO
#   UDRW - DMG
hdiutil convert -format "${FORMAT}" -o disk.iso disk.dmg

# OR
hdiutil makehybrid -iso -joliet -o disk.iso disk.cdr

rEFInd

  • Reboot into recovery, create new partition of size 256MB

  • Run

    bash
    csrutil disable
  • Reboot

  • Run

    bash
    diskutil list
    sudo ./refind-install --ownhfs /dev/disk0sX

MacPorts

~/.profile
export PATH="/opt/local/bin:/opt/local/sbin:$PATH"

Base packages

  • moreutils

  • iTerm2

  • wget

  • autossh

  • gnupg21

  • syncthing-0.14

  • vim +perl +lua +python35 +ruby MacVim

  • pwgen

  • ncdu

  • pv

  • the_silver_searcher

  • watch

  • cmake

  • aria2

  • pixz

  • lrzip

  • unrar

  • htop

  • xorg-server rxvt-unicode

  • borgbackup

  • ffmpeg

  • android

Homebrew

Remove Homebrew

bash
sudo ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"
sudo chmod 0755 /usr/local
sudo chown root:wheel /usr/local

Install Homebrew

  • Run

    bash
    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
    brew doctor
    brew analytics off
  • Install Xcode

  • Run

    bash
    sudo xcodebuild -license

Packages

homebrew/fuse/sshfs macvim vim
pwgen syncthing moreutils pv ncdu gptsync watch
  • For syncthing service, just run brew services start syncthing

  • Gnu tools requires –with-default-names, otherwise it will install /usr/local/bin/gsed instead of sed: brew install gnu-sed --with-default-names

Get rid of Mac garbage

System Preferences
Spotlight > Disable Spotlight Suggestings
Security and Privacy > Privacy > Location Services > System Service Details... > Disable Spotlight

SSH Config

/etc/sshd_config
Protocol 2
UseDNS no
PermitEmptyPasswords no
PermitRootLogin no

# Disable password authentication for a user/group
Match Group nopasswd
  PasswordAuthentication no
  kbdInteractiveAuthentication no
Match User backuppc,stonewareslord
  PasswordAuthentication no
  kbdInteractiveAuthentication no

Rsync Backup

Newer version

root sh
set -euxo pipefail
TARGET_DRIVE="/Volumes/BackupDisk"

if [[ ! -d "/${TARGET_DRIVE}" ]]; then
	echo "Target drive ${TARGET_DRIVE} does not exist"
	exit 2
fi

sudo time rsync                             \
	--acls                              \
	--xattrs                            \
	--hard-links                        \
	--group                             \
	--owner                             \
	--numeric-ids                       \
	-D                                  \
	--protect-decmpfs                   \
	--links                             \
	--recursive                         \
	--times                             \
	--perms                             \
	--one-file-system                   \
	--crtimes                           \
	--fileflags                         \
	--force-change                      \
	--protect-args                      \
	--delete-before                     \
	--ignore-errors                     \
	--filter='._/Users/i/.rsync-filter' \
	/                                   \
	"${TARGET_DRIVE}"

bless -folder "${TARGET_DRIVE}/System/Library/CoreServices"

Older version

root sh
# Backup everything important, note trailing slashes
rsync -vaxE -S --delete --exclude-from=exclude.txt "/" "/Volumes/hd/"
# Make it bootable
bless --folder /Volumes/hd/System/Library/CoreServices
exclude.txt
.HFS+\ Private\ Directory\ Data
/.journal
/.journal_info_block
.AppleDouble
/lost+found
.metadata_never_index
.com.apple.timemachine.donotpresent
.VolumeIcon.icns
/TheVolumeSettingsFolder
Saved\ Application\ State
.DocumentRevisions-V100
.Spotlight-V100
.fseventsd
/.fseventsd
/.hotfiles.btree
/private/var/db/dyld/dyld_*
/System/Library/Caches/com.apple.bootstamps/*
/System/Library/Caches/com.apple.corestorage/*
/System/Library/Caches/com.apple.kext.caches/*
/.com.apple.NetBootX
/Volumes/*
/dev/*
/automount
/Network
/.vol/*
/net
/private/var/folders/*
/private/var/vm/*
/private/tmp/*
/cores
.Trash
.Trashes
/Backups.backupdb
/.MobileBackups

Misc

  • Allow all network disks for time machine

    bash
    defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1
  • Enable VNC

    bash
    sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate -configure -access -on -clientopts -setvnclegacy -vnclegacy yes -clientopts -setvncpw -vncpw securepassword -restart -agent -privs -all
  • Disable VNC

    bash
    sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -deactivate -configure -access -off
  • Disable screenshot drop shadow

    bash
    defaults write com.apple.screencapture disable-shadow -bool true
    killall SystemUIServer
  • Startup Chime

    bash
    # Disable
    sudo nvram SystemAudioVolume=%80
    # Enable
    sudo nvram -d SystemAudioVolume
  • To install Virtualbox

    bash
    sudo installer -package /Volumes/VirtualBox/VirtualBox.pkg -target /
  • To enable "Allow apps downloaded from anywhere

    bash
    sudo spctl --master-disable
  • To prevent Mac from sleeping, run

    bash
    # Disable sleep for an hour
    caffeinate -t 3600
    # Disable sleep until a command completes
    caffeinate -i sh -c 'command'
    # To simulate wakeup by mouse movement
    caffeinate -u -t 1
  • PageUp on Mac is just Fn+Up

  • Option+Click on Green Plus maximizes a window as expected in later OS X

  • To disable mouse acceleration, run

    bash
    defaults write .GlobalPreferences com.apple.mouse.scaling -1

Misc Commands

urxvt

  • Run

    bash
    sudo port install xorg-server rxvt-unicode
  • Copy ~/.Xresources to ~/.Xdefaults

  • Append

    ~/.Xdefaults
    URxvt.perl-ext-common: macosx-clipboard
    URxvt*keysym.M-c: perl:macosx-clipboard:copy
    URxvt*keysym.M-v: perl:macosx-clipboard:paste
  • Run

    bash
    xrdb ~/.Xdefaults

Windows

Tools/Apps

Common apps

regedit
gpedit.msc
diskmgmt.msc
devmgmt.msc
msconfig
dxdiag
gpupdate

Useful tools

Install Windows 10 on external hard drive (10)

  1. Boot into installer environment

  2. Shift+F10

  3. ;

Admin cmd
list disk
select disk x (where x your disk number 0,1,2,3,... and so on)
clean (This will format the whole disk)
convert gpt
create partition primary size=350
format quick fs=ntfs label="Windows RE Tools"
assign letter="T"
set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac"
gpt attributes=0x8000000000000001
create partition efi size=100
REM NOTE: For Advanced Format 4Kn drives, change this value to size = 260
format quick fs=fat32 label="System"
assign letter="S"
create partition msr size=128
create partition primary size=512000
format quick fs=ntfs label="Windows"
assign letter="W"
create partition primary size=4096
format quick fs=ntfs label="Recovery Image"
assign letter="R"
set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac"
gpt attributes=0x8000000000000001
list volume
exit
REM Remain in CMD

C:
REM Type Dir to check if it's your Windows 10 bootable pendrive. If not, use diskpart to verify your pendrive volume letter. list volume command in the above script shows the drive letter of your pendrive.

REM TODO: One of these wims does not exist. Figure out which one and fix it here
md R:\RecoveryImage
copy C:\sources\install.wim R:\RecoveryImage\install.wim
cd X:\Windows\System32
dism /Apply-Image /ImageFile:R:\RecoveryImage\install.wim /Index:1 /ApplyDir:W:\
md T:\Recovery\WindowsRE
copy W:\Windows\System32\Recovery\winre.wim T:\Recovery\WindowsRE\winre.wim
bcdboot W:\Windows /s S: /f UEFI
W:\Windows\System32\reagentc /setosimage /path R:\RecoverImage /target W:\Windows /index 1
W:\Windows\System32\reagentc /setreimage /path T:\Recovery\WindowsRE /target W:\Windows

Disable users

Admin cmd
net user username /active:no
REM To re-enable
net user username /active:yes

Enable gpedit.msc

enableGedit.bat
@echo off
pushd "%~dp0"

dir /b %SystemRoot%\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum >List.txt
dir /b %SystemRoot%\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientTools-Package~3*.mum >>List.txt
for /f %%i in ('findstr /i . List.txt 2^>nul') do dism /online /norestart /add-package:"%SystemRoot%\servicing\Packages\%%i"
pause

Automatic Login

  • Run netplwiz

  • Or: CONTROL USERPASSWORDS2

  • Pick user for automatic login

  • Uncheck top checkbox

  • Type password if prompted

Disable Windows Garbage

  • Disable Internet Explorer alwyas checking if it is default browser

    gpedit.msc
    Disable: User Configuration\Administrative Templates\Windows Components\Internet Explorer\Notify users if Internet Explorer is not the default web browser
  • Disable OneDrive

    gpedit.msc
    Disable: Computer Configuration\Administrative Templates\Windows Components\OneDrive
  • Disable Windows Defender

    gpedit.msc
    Disable: Computer Configuration\Administrative Templates\Windows Components\Windows Defender
  • Disable “Windows is checking a solution to the problem…”

    gpedit.msc
    Enable: Computer Configuration\Administrative Templates\Windows Components\Windows Error Reporting\Disable Windows Error Reporting
  • Disable Homegroup

    services.msc
    Stop and Disable: HomeGroupProvider
    Stop and Disable: HomeGroupListener

Install Chocolatey

Admin Powershell
@powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin
Some good Chocolatey packages
sudo
GoogleChrome Firefox
vim filezilla putty git f.lux vlc

Tell Windows to use UTC

utcTime.reg
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation]
"RealTimeIsUniversal"="1"

Fully remove OneDrive

disableOneDrive.bat
@echo off
cls
set x86="%SYSTEMROOT%\System32\OneDriveSetup.exe"
set x64="%SYSTEMROOT%\SysWOW64\OneDriveSetup.exe"
echo Closing OneDrive process.
echo.
taskkill /f /im OneDrive.exe > NUL 2>&1
timeout 5
echo Uninstalling OneDrive.
echo.
if exist %x64% (
%x64% /uninstall
) else (
%x86% /uninstall
)
timeout 5
echo Removing OneDrive leftovers.
echo.
rd "%USERPROFILE%\OneDrive" /Q /S > NUL 2>&1
rd "C:\OneDriveTemp" /Q /S > NUL 2>&1
rd "%LOCALAPPDATA%\Microsoft\OneDrive" /Q /S > NUL 2>&1
rd "%PROGRAMDATA%\Microsoft OneDrive" /Q /S > NUL 2>&1
echo Removing OneDrive from the Explorer Side Panel.
echo.
REG DELETE "HKEY_CLASSES_ROOT\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}" /f > NUL 2>&1
REG DELETE "HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}" /f > NUL 2>&1
pause

Uninstall all Windows tile apps (8-10)

Admin Powershell
Get-AppxPackage -AllUsers | Remove-AppxPackage

Disable Windows Hard Drive Swap/Hibernation

  • Turn off hibernation

    Control Panel
    Power Options > Change what the power button does > Change settings that are currently unavailable > Turn off fast startup
  • Run

    Admin cmd
    powercfg.exe -h off
  • Turn off swap

    Control Panel
    Advanced System Settings > Advanced > Performance > Settings > Advanced > Virtual Memory > Change > Unckeck Automatically manage paging file size for all drives > No paging file
  • Run

    Admin cmd
    wmic computersystem where name="%computername%" set AutomaticManagedPagefile=False
  • Reboot

  • Run

    Admin cmd
    wmic pagefileset where name="C:\pagefile.sys" delete
  • Turn off System Protection

    Control Panel
    Advanced System Settings > System Protection > Configure > Turn off system protection

Disable Windows Telemetry (10)

gpedit.msc
Disable: Computer Configuration\Administrative Templates\Windows Components\Data Collection and Preview Builds\Allow Telemetry
services.msc
Stop and Disable: Connected User Experiences and Telemetry
Stop and Disable: dmwappushsvc
Admin cmd
sc delete DiagTrack
sc delete dmwappushservice
echo "" > C:\ProgramData\Microsoft\Diagnosis\ETLLogs\AutoLogger\AutoLogger-Diagtrack-Listener.etl
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" /v "AllowTelemetry" /d "0" /f
Settings tile app
Update and Security > Advanced Options > Choose how updates are delivered, and turn the first switch off

Windows Classic Theme (8-10)

Disable Cortana/Searching completely (10)

Admin cmd
taskkill /f /im SearchUI.exe & timeout 1 & ren "C:\Windows\SystemApps\Microsoft.Windows.Cortana_cw5n1h2txyewy" Microsoft.Windows.Cortana_cw5n1h2txyewy.bak

Enable dark mode (10)

Admin Powershell
New-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name AppsUseLightTheme -Value 0
New-ItemProperty -Path HKCM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name AppsUseLightTheme -Value 0

Disable some “Upgrade” to Windows 10 nonsense (7-8.1)

Programs and Features > Installed Updates
* Uninstall and hide the following updates
** `+KB3035583+`: GWX Update installs Get Windows 10 app in Windows 8.1 and Windows 7 SP1
** `+KB3021917+`: Update to Windows 7 SP1 for performance improvements
** `+KB3012973+`: Upgrade to Windows 10 Pro
** `+KB3139929+`: Internet Explorer ad generator for windows 10, hidden in a security update
Admin cmd
:: Add some keys, just in case
:: Disable Gwx entirely
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Gwx" /v "DisableGwx" /d "1" /f
:: Set the reservations to 0
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\OSUpgrade" /v "ReservationsAllowed" /d "0" /f

Allow all updates (XP)

  • Download and run

    updates.reg
    Windows Registry Editor Version 5.00
    [HKEY_LOCAL_MACHINESYSTEMWPAPosReady]
    "Installed"=dword:00000001

Misc

When Windows installations fail

Windows Installer
* `+Shift+F10+` will open a commannd prompt
* To fix a frozen installation, run

+

Admin cmd
tasklist -v | findstr cmd
  • Search for a pid with process/windown name that includes $oem$ or kb

  • Run

    Admin cmd
    taskkill /pid 12345

Lock screen with shortcut

New Shortcut
rundll32.exe user32.dll, LockWorkStation

Disable sppsvc

disableSppsvc.reg
disableSppsvc.reg>
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sppsvc]
"Start"=dword:00000004

Eject DVD drive every 2 minutes after 10 minutes

dvd.vbs
Set oWMP = CreateObject("WMPlayer.OCX.7")
Set colCDROMs = oWMP.cdromCollection
wscript.sleep 600000
do
if colCDROMs.Count >= 1 then
For i = 0 to colCDROMs.Count - 1
colCDROMs.Item(i).Eject
Next
For i = 0 to colCDROMs.Count - 1
colCDROMs.Item(i).Eject
Next
End If
wscript.sleep 120000
loop

Misc

Install borgbackup

root sh
apt update
apt install python3-pip libssl-dev libacl1-dev python3-llfuse
pip3 install borgbackup

Use Apple’s SuperDrive on Linux

Need to send magic sequence to the drive to enable it:

bash
# On Debian
sudo apt install sg3-utils
# On Gentoo
sudo emerge sg3_utils

sg_raw /dev/sr1 EA 00 00 00 00 00 01

To make this an automatic process:

/etc/udev/rules.d/99-local.rules
ACTION=="add", ATTRS{idProduct}=="1500", ATTRS{idVendor}=="05ac", DRIVERS=="usb", RUN+="/usr/bin/sg_raw /dev/$kernel EA 00 00 00 00 00 01"

Handbrake Encoding

To encode a video, capture all subtitles (or at least the first 9 tracks), and extract all audio channels:

bash
HandBrakeCLI -i /dev/sr0 -s "1,2,3,4,5,6,7,8,9," --all-audio -o out.mp4

Joplin setup

Install the CLI

bash
NPM_CONFIG_PREFIX=~/applications/joplin-bin npm install -g joplin
ln -s NPM_CONFIG_PREFIX=~/applications/joplin-bin/bin/joplin ~/bin/joplin-cli

Configure Sync

bash
# Set the sync target to a local directory
joplin-cli config sync.target 2
# Set the sync path
joplin-cli config sync.2.path ~/joplin
# Perform the initial sync
joplin-cli sync

Setup

bash
joplin-cli config trackLocation false
joplin-cli config dateFormat YYYY-MM-DD
joplin-cli config timeFormat "h:mm A"

Install python3.6 in debian

root sh
echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list
# Be sure to replace stable with whatever's in /etc/apt/sources.list
# Could be stable, jessie, ...
echo 'APT::Default-Release "stable";' > /etc/apt/apt.conf.d/00local
apt update
apt -t testing install python3.6

To disable git in Eclipe

bash
cd /path/to/eclipse
mkdir -p disabled/{featres,plugins}
mv features/*egit* disabled/features/
mv plugins/*jgit* disabled/plugins/
mv plugins/*egit* disabled/plugins

Debian java

bash
echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu xenial main" | sudo tee /etc/apt/sources.list.d/webupd8team-java.list
echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu xenial main" | sudo tee -a /etc/apt/sources.list.d/webupd8team-java.list
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886
sudo apt-get update
sudo apt-get install oracle-java8-installer

Debian node

bash
# From: https://github.com/nodesource/distributions/blob/master/README.md
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
apt install nodejs # Optional: build-essential

Debian php7.1

root sh
wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
apt install apt-transport-https
apt update
apt install php7.1-common  php7.1-readline php7.1-fpm php7.1-cli php7.1-gd php7.1-mysql php7.1-mcrypt php7.1-curl php7.1-mbstring php7.1-opcache php7.1-json

Debian php7.0

root sh
# Configure sources
apt update
apt install -y wget apt-utils
echo 'deb http://packages.dotdeb.org jessie all' >> /etc/apt/sources.list
echo 'deb-src http://packages.dotdeb.org jessie all' >> /etc/apt/sources.list
wget https://www.dotdeb.org/dotdeb.gpg -O /tmp/dotdeb.gpg
apt-key add /tmp/dotdeb.gpg
rm /tmp/dotdeb.gpg
# Install php
apt update
apt install -y php7.0
# Misc modules
apt install php7.0-{gd,xml,ssh2,sqlite3,xmlrpc,zip,mysql,opcache,odbc,pgsql,phpdbg,readline,pspell,redis,tidy,memcached,mcrypt,mbstring,json,imap,imagick,gmp,intl,dev,dbg,fpm,geoip,curl,cli,cgi,bz2,bcmath,apcu}

Tar Backup

Create then compress (without pixz)

  • Create

    bash
    tar --one-file-system --xattrs -cpf - -C /root/directory/to/backup ./ | pv -N tar > /path/to/destination/backup.tar
  • Compress

    bash
    pxz -9 /path/to/destination/backup.tar /path/to/destination/backup.tpixz

Create/Compress at once (with pixz)

  • Create

    bash
    tar --one-file-system --xattrs -cpf /path/to/destination/backup.tpixz -C /root/directory/to/backup -I pixz ./
  • View creation progress

    bash
    progress -mc pixz -c tar
  • Encrypt and split

    bash
    pv -WcN tpixz /path/to/destination/backup.tpixz | gpg -er user1 -r user2 -r user3 | pv -WcN gpg | split -b 256M - /path/to/destination/x
  • List contents

    bash
    pixz -l /path/to/destination/backup.tpixz
  • Restore

    bash
    pv -WcN files /path/to/destination/x* | gpg -d | pv -WcN gpg > /path/to/destination/backup.tpixz
    pixz -d /path/to/destination/backup.tpixz /path/to/destination/backup.tar
    pv /path/to/destination/backup.tar | tar --xattrs -C /root/path/to/extract -xpf -

Run HP Calculator on linux

  • Make sure the kernel supports it

    bash
    zcat /proc/config.gz | grep -E CONFIG_USB_SERIAL(_GENERIC)?=
  • Plug in calculator

  • Load modules

    bash
    sudo modprobe -v usbserial option
    echo 03f0 0121 | sudo tee /sys/bus/usb-serial/drivers/option1/new_id
  • Run kermit

    bash
    sudo ./kermit -l /dev/ttyUSB0
  • Use kermit

    # Initialize
    set carrier-watch off
    robust
    # Receive a file (afterwords on calculator go to Files>Send)
    server
    # Send files (first on calculator go to Files>Recieve)
    send file

Reset HP calculator

  • Hold ON and F6 for two seconds then release and press ON

Set Virtualbox time back x years

bash
export MACHINE=""
export YEARS=""
# Disable getting the time from the host machine
VBoxManage setextradata "$MACHINE" "VBoxInternal/Devices/VMMDev/0/Config/GetHostTimeDisabled" 1
# Set the time back
VBoxManage modifyvm "$MACHINE" --biossystemtimeoffset $((-31536000000*$YEARS))

Android

Termux

packages
aria2
ffmpeg
file
git
gnupg
golang
htop
hunspell
imagemagick
man
ncdu
pass
perl
php
proot
pv
pwgen
rsync
strace
termux-api
texlive-bin
tmux
vim
wget

Install duplicity

termux sh
apt update
apt install openssl-dev libffi-dev librsync-dev python2-dev python2 gnupg2 libcrypt-dev
pip2 install duplicity paramiko

Wipe Android userdata

su
# Find the userdata partition
ls /dev/block/.../userdata
# Destroy header
dd if=/dev/zero of=$USERDATA bs=4096 count=512
# Finally run mkfs.ext4
make_ext4fs /dev/block/.../userdata

Disable Google location services

su
pm disable com.google.android.gms/com.google.android.location.internal.GoogleLocationManagerService
pm disable com.google.android.gms/com.google.android.location.network.NetworkLocationService
pm revoke com.google.android.gms android.permission.ACCESS_FINE_LOCATION
pm revoke com.google.android.gms android.permission.ACCESS_COARSE_LOCATION

OP3 Linux ADB

bash
mkdir -p ~/.android
echo 0x2A70 >> ~/.android/adb_usb.ini
adb kill-server
adb shell

Disable Direct Share

  • Remount system in rw

  • Create the following directory/file

    /data/system/ifw/directshare.xml
    <rules>
        <service block="true" log="true">
            <intent-filter>
                <action name="android.service.chooser.ChooserTargetService" />
            </intent-filter>
        </service>
    </rules>
  • Or run

    root bash
    mount -o remount,rw /system
    printf '<rules><service block="true" log="true"><intent-filter><action name="android.service.chooser.ChooserTargetService" /></intent-filter></service></rules>' > /data/system/ifw/directshare.xml
    mount -o remount,ro /system

Enable OnePlus adb in Linux

  • Run

    bash
    mkdir ~/.android
    echo "0x2a70" >> ~/.android/adb_usb.ini

Android Shell Commands

  • Disable captive portal

    adb shell root
    settings put global captive_portal_detection_enabled 0
    # This is new from ~7.1.2
    settings put global captive_portal_mode 0
  • Set Nexus 5 DPI

    adb shell
    adb shell wm density 493
  • Open app

    adb shell
    adb shell monkey -p APP.PACKAGE.NAME 1
  • Show all packages

    adb shell
    adb shell pm list packages -f
  • Kill application

    adb shell
    adb shell am force-stop APP.PACKAGE.NAME

Rsync to Android

bash
wget -O rsync.bin http://github.com/pts/rsyncbin/raw/master/rsync.rsync4android
adb push rsync.bin /data/local/tmp/rsync
adb shell chmod 755 /data/local/tmp/rsync
adb shell cp /data/local/tmp/rsync /sdcard/rsync.bin
adb shell 'exec >/sdcard/rsyncd.conf && echo address = 127.0.0.1 && echo port = 1873 && echo "[root]" && echo path = / && echo use chroot = false && echo read only = false'
adb shell /data/local/tmp/rsync --daemon --no-detach --config=/sdcard/rsyncd.conf --log-file=/proc/self/fd/2
adb forward tcp:6010 tcp:1873

#Doesn't work well if you're copying to android (gid, uid error)
rsync -ha --info=progress2 --stats rsync://localhost:6010/root/sdcard/ sdcard/

Base Ubuntu Install

The following is a guide for setting up a base Ubuntu install ## Initial Commands

bash
gsettings set com.canonical.Unity.Dash scopes "['home.scope', 'applications.scope', 'files.scope']"
sudo add-apt-repository universe
sudo add-apt-repository multiverse
sudo apt update
sudo apt upgrade
sudo apt dist-upgrade
sudo apt autoremove
sudo reboot

Important Packages

  • Critical

    • lsb-core: Important for certain programs

  • Media

    • vlc

    • libdvdread4/libdvd-pkg(15.10+): Allow dvd playback

    • ubuntu-restricted-extras: Extra media

    • ttf-mscorefonts-installer: Times New Roman and more fonts

  • Programming

    • git zsh build-essential cmake make tmux screen

  • QtPass

    • git pass gnupg2 qtpass

  • Misc

    • compizconfig-settings-manager: Gui swiches

    • moreutils: Cool utilities

  • Debugging

    • htop nload nethogs hardinfo multitail

Settings

  • Software and Updates > Ubuntu Software > Check top four boxes > Updates > Notify me of a new Ubuntu version > Never > Close > Close: Enable all sources and don’t upgrade to buggy 16.04

  • Security and Privacy > Search > Include Online Search Results > Off > Diagnostics > Uncheck Send error reports to Canonical > Off: Enable misc privacy features

Disable annoying xubuntu zoom

  • Settings Editor > xfwm4 > Disable xfwm4

Disable Apport

/etc/default/apport
enabled=0

Misc

  • Unlock Amazon Shopping, Libreoffice (Lock black Libreoffice icon)

  • Run

    bash
    sudo apt remove unity-webapps-common

Degugging

  • To allow paste shortcut, run

    bash
    echo 'curl --data-urlencode text@- -d title="Command run at $(date +%d/%h/%y %H:%M:%S) on $(hostname)" -d name=$USER -d expire="40320" https://austen-wares.com/paste/api/create' | tee -a ~/.bashrc ~/.zshrc >/dev/null

PPAS

Yarn

bash
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list

Signal

bash
curl -s https://updates.signal.org/desktop/apt/keys.asc | sudo apt-key add -
echo "deb [arch=amd64] https://updates.signal.org/desktop/apt xenial main" | sudo tee /etc/apt/sources.list.d/signal-xenial.list
sudo apt update && sudo apt install signal-desktop

Nextcloud

bash
sudo add-apt-repository ppa:nextcloud-devs/client --no-update
sudo apt update
sudo apt install nextcloud-client

Riot

bash
sudo apt install -y wget apt-transport-https
sudo wget -O /usr/share/keyrings/riot-im-archive-keyring.gpg https://packages.riot.im/debian/riot-im-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/riot-im-archive-keyring.gpg] https://packages.riot.im/debian/ default main" | sudo tee /etc/apt/sources.list.d/riot-im.list
sudo apt update
sudo apt install element-desktop

Telegram

bash
sudo add-apt-repository ppa:atareao/telegram --no-update
sudo apt update
sudo apt install telegram telegram-cli

Libreoffice

bash
sudo add-apt-repository ppa:libreoffice/ppa --no-update
sudo apt update
sudo apt install libreoffice

Java

bash
sudo add-apt-repository ppa:webupd8team/java --no-update
sudo apt update
sudo apt install oracle-java9-installer oracle-java9-set-default

OBS

bash
sudo apt-add-repository ppa:obsproject/obs-studio
sudo apt update
sudo apt install ffmpeg obs-studio

Wire

bash
sudo apt update
sudo apt install apt-transport-https wget
wget -q https://wire-app.wire.com/linux/releases.key -O- | sudo apt-key add -
echo "deb https://wire-app.wire.com/linux/debian stable main" | sudo tee /etc/apt/sources.list.d/wire-desktop.list
sudo apt update
sudo apt install wire-desktop

Install Gentoo

Initial Setup

Partition Table

bash
parted -a optimal /dev/sda
mklabel gpt
unit mib
  • Run

    bash
    test -f /sys/firmware/efi&&echo EFI||echo BIOS
  • If on BIOS, run

    bash
    mkpart primary 1 3
    name 1 grub
    set 1 bios_grub on
  • If on EFI, run

    parted
    mkpart primary 1 201
    name 1 EFI
    set 1 boot on
  • IDs

    gdisk ids
    8200 Linux swap
    8300 Linux filesystem
    af00 Apple HFS/HFS+
    ef00 EFI System
    ef02 BIOS Boot
  • Run

    parted
    mkpart primary $LAST_ENDPOINT 643
    name 2 swap
    mkpart primary 643 -1
    name 3 root
    print
    quit

Partitions

Optionally, you can fully encrypt your hard drive by Using LUKS

bash
mkswap /dev/sda2
swapon /dev/sda2
mkfs.ext4 /dev/sda3

Base Install

bash
mount /dev/sda3 /mnt/gentoo
cd /mnt/gentoo
rsync --partial --info=progress2 -ha austen-wares.com::public/gentoo/ .
sha512sum -c SHA512SUMS && rm -f SHA512SUMS
tar xjpf stage3.tbz

System Setup

Chroot

bash
cp -L /etc/resolv.conf /mnt/gentoo/etc/
mount -t proc{,,}
mount --rbind {/,}sys
mount --rbind {/,}dev
chroot /mnt/gentoo /bin/bash

User Interactive Setup

bash
nano -w /etc/fstab
nano -w /etc/conf.d/hostname
nano -w /etc/hosts

Portage Setup

bash
mkdir -p /usr/portage
  • Run either

    bash
    rsync --partial --info=progress2 -ha austen-wares.com::portage/ /usr/portage/
  • Or

    bash
    cd /usr/portage
    wget https://gitea.austen-wares.com/stonewareslord/portage/archive/master.tar.gz
    tar -xf master.tar.gz
    rm master.tar.gz
    bash
    eselect profile list
    eselect profile set $PROFILE
    eselect profile list

Locale Setup

bash
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
locale-gen
eselect locale set en_US.utf8

Misc Setup

bash
echo "US/Eastern" > /etc/timezone
emerge --config sys-libs/timezone-data
emerge -v gentoo-sources syslog-ng cronie dhcpcd sys-boot/grub genkernel
rc-update add syslog-ng default
rc-update add cronie default
rc-update add sshd default

Kernel Setup

bash
genkernel --makeopts="-j$(nproc)" all
grub-install /dev/sda
grub-mkconfig -o /boot/grub/grub.cfg

Cleanup

bash
rm /stage3.tbz
exit
reboot

Post Install

bash
perl-cleaner --reallyall
emerge --update --newuse --deep --with-bdeps=y @world
emerge @preserved-rebuild
python-updater
/etc/portage/make.conf
# Sanitize breaks gcc and we don't need bindist
USE="-bindist -sanitize"
# Optionally use my binhost
EMERGE_DEFAULT_OPTS="-gkv --nospinner"
PORTAGE_BINHOST="rsync://austen-wares.com/binhost/amd64"
# Emerge will complain if this isn't set, only needed if using binhost
PORTAGE_SSH_OPTS=""
/etc/portage/package.use/package.mask
# Later versions of this are dangerous
>sys-devel/gcc-4.9.3

Zsh

General

  • ===== Selection

    GoalOperatorExampleNotes

    Iterator

    {0..10}

    0 1 2 3 4 5 6 7 8 9 10

    Only directories

    (/)

    Only files

    (.)

    Empty files

    (L0)

    Files with a size of zero

    File size

    (Lk+3)

    Files with a size of greater than 3 kilobytes

    Modification date

    (mh-1)

    Files with a modification date since one hour ago

    M - month, w - week, h - hour, m - minute, s - second

    Sort

    (om)

    Sort by (m)odification time

    Use capital to reverse order

    Slice array

    ([1-3])

    Only get the first through third result

Files

Examples using /home/user/file.jpg

GoalOperatorResult

File name only

(:t)

file.jpg

Cut off extension

(:r)

/home/user/file

Extension only

(:e)

jpg

Parent directory

(:h)

/home/user

Uppercase

(:u)

/HOME/USER/FILE.JPG

zsh
# Substitute
# / could be replaced by any character
(:s/src/dest/)
(:s_src_dest_)
# Example

    *(:s/xxx/yyy/)
  # Use gs for global
  # aaa -> Aaa
  $var(:s/a/A)
  # aaa -> AAA
  $var(:gs/a/A)

Misc

  • Expansion flags

    zsh
    # Split by char
    # Split by _
    $var(:s._.)
    # Join by char
    # Join by _
    $var(:j._.)
  • Event designator

    zsh
    # Run second to last command
    !-2
    # Last argument of last command
    !!$
    # All arguments of last command
    !!*
    # All except first argument of last command
    !!2*
  • Null Globs

    zsh
    # If dir is empty, this will fail
    dir/*
    # But this will return ""
    dir/*(N)
  • Directories without nopick file

    zsh
    %%**/*(e:'[[ ! -e $REPLY/.bupignore ]]')%%

LXD

Use DNS domains

root sh
lxc network set lxdbr0 dns.domain lxd
lxc network set lxdbr0 dns.mode managed
# Add nameserver to resolv.conf
echo nameserver 10.0.3.1 >> /etc/resolv.conf.head
rc-service dhcpcd restart

Create from tarball

  • Get a tarball of the rootfs (compressed is fine)

  • Create metadata.yaml

    bash
    architecture: x86_64
    creation_date: 1492631766
    config:
      image.architecture: amd64
      image.description: Distrubution amd64 (20170419_03:54)
    image.os: Distrubution
    image.release: 8.0
  • Run

    bash
    tar -cf metadata.{tgz,yaml}
    lxc image import metadata.tgz rootfs.tbz2 --alias distrobution

Profiles

  • Create

    root bash
    lxc profile create PROFILE
  • Show

    root bash
    lxc profile edit PROFILE
  • Edit

    root bash
    lxc profile edit PROFILE
  • Apply

    root bash
    lxc profile apply CONTAINER PROFILE[,PROFILE2,PROFILE3...]

Limits

  • Memory

    root bash
    # Set memory limit
    lxc config set CONTAINER limits.memory 256MB
    lxc profile set PROFILE limits.memory 256MB
    # ^ keep in mind swap is still available
    # Turn off swap
    lxc config set CONTAINER limits.memory.swap false
    lxc profile set PROFILE limits.memory.swap false
    # Tell kernel to swap this memory first
    lxc config set CONTAINER limits.memory.swap.priority 0
    lxc profile set PROFILE limits.memory.swap.priority 0
    # If you don't want hard memory limit enforced
    lxc config set CONTAINER limits.memory.enforce soft
    lxc profile set PROFILE limits.memory.enforce soft
  • CPU

    root bash
    # Use only 2 CPUs
    lxc config set CONTAINER limits.cpu 2
    lxc profile set PROFILE limits.cpu 2
    # Use CPU core 1 and 3 and 5-7
    lxc config set CONTAINER limits.cpu 1,3,5-7
    lxc profile set PROFILE limits.cpu 1,3,5-7
    # Enforce an allowance
    lxc config set CONTAINER limits.cpu.allowance 10%
    lxc profile set PROFILE limits.cpu.allowance 10%
    # Set to minimum priority
    lxc config set CONTAINER limits.cpu.priority 0
    lxc profile set PROFILE limits.cpu.priority 0
  • Disk

    root bash
    # Enforce 20GB disk (ZFS only)
    lxc config device set CONTAINER root size 20GB
    lxc profile device set PROFILE root size 20GB
    # Restrict writing speed
    lxc config device set CONTAINER root limits.read 30MB
    lxc config device set CONTAINER root.limits.write 10MB
    lxc profile device set PROFILE root limits.read 30MB
    lxc profile device set PROFILE root.limits.write 10MB
  • Files

    root bash
    lxc config set CONTAINER lxc.limit.nofile unlimited
    lxc profile device set PROFILE lxc.limit.nofile unlimited

Notes

  • Setup mappings

    root bash
    # Get something up and running
    lxc launch ubuntu
    grep id_map /var/log/lxd/first/lxc.conf
    # lxc.id_map = u 0 1000000 1000000000
    # lxc.id_map = g 0 1000000 1000000000
    echo "root:1000000:1000000000" >/etc/sub{u,g}id
  • Add a mount

    root bash
    mkdir /opt/lxd/mysql-data
    ls -l
    chmod -R 1000000:1000000 /opt/lxd/mysql-data
    lxc config device add mysql mysql-data disk path=/var/lib/mysql source=/opt/lxd/mysql-data
  • Correctly copy directory with permissions over

    container root bash
    tar -cpf /tmp/a.tar -C /etc ./
    root bash
    lxc file pull container/tmp/a.tar .
    tar --numeric-owner -xf a.tar
    chown -R --from=0 1000000:1000000 .
  • Networking

    root bash
    # Create a network
    lxc network create testbr0
    # Create a network with custom network
    lxc network create testbr0 ipv6.address=none ipv4.address=10.0.3.1/24 ipv4.nat=true
    # Show info
    lxc network show testbr0
    # Set this network as the default for new containers
    lxc network attach-profile testbr0 default eth0
    # Set this network as the default for one container
    lxc network attach testbr0 container eth0
    # Use a static lease
    lxc config device set container eth0 ipv4.address 10.0.3.123
    # Detach a network from a container
    lxc network detach testbr0 container
    # Detach a network from a profile
    lxc network detach-profile testbr0 default
    # Delete a network
    lxc network delete testbr0
  • Export an image

    root bash
    # Export
    lxc publish container --alias container-image
    lxc image list
    lxc image export container-image .
    # Import
    lxc image import hash.tar.gz --alias container-image
  • Misc

    root bash
    lxc image list images: | less
    # Start on boot
    lxc config set container_name boot.autostart 1
  • More

Firefox

Remove animations

about:config
toolkit.cosmeticAnimations.enabled; false

Custom Firefox sync server

On both Firefox Desktop and Mobile:

about:config
identity.sync.tokenserver.uri;https://syncserver.austen-wares.com/token/1.0/sync/1.5

Dark tab load page

When tabs have not yet loaded, set the background dark (it still flashes when using addons though)

about:config
toolkit.legacyUserProfileCustomizations.stylesheets;true
~/.mozilla/firefox/*/chrome/userChrome.css
browser[type="content-primary"], browser[type="content"] {
  background: #121212 !important;
}
~/.mozilla/firefox/*/chrome/userContent.css
@-moz-document url-prefix(about:blank) {
    html > body:empty {
        background-color: #121212 !important;
    }
}
@-moz-document url(about:blank) {
    html > body:empty {
        background-color: #121212 !important;
    }
}

Tree style tab

In FF57, the old tree style tab addon stopped working and was replaced with a newer one: I use a few customziations that make it look nicer:

~/.mozilla/firefox/*/chrome/userChrome.css
#main-window[tabsintitlebar="true"]:not([extradragspace="true"]) #TabsToolbar {
  opacity: 0;
  pointer-events: none;
}
/* Hide the title bar tabs */
#main-window:not([tabsintitlebar="true"]) #TabsToolbar {
  visibility: collapse !important;
}
/* Hide the sidebar title */
#sidebar-box[sidebarcommand="treestyletab_piro_sakura_ne_jp-sidebar-action"] #sidebar-header {
  display: none;
}
/* Allow a smaller sidebar */
#sidebar {
  min-width: 28px !important;
}
/* Honestly don't know what this is for, but it was in my userChrome.css file so */
#aHTMLTooltip {
  display: none !important
}
Advanced > Extra Style Rules
/* Show title of unread tabs with red and italic font */
/*
.tab.unread .label {
  color: red !important;
  font-style: italic !important;
}
*/
/* Change tab height and width */
.tab {
  height: 25px;
  padding-left: 7px;
}
/* Hide twisty */
.tab .twisty {
  display: none;
}
/* Hide the new tab button */
.newtab-button-box {
  display: none;
}
#tabbar {
  bottom: 0 !important; /* Eliminate dead space on bottom */
}

about:config

  • ui.prefersReduceMotion;0: 0 for "No preference", 1 for "Reduce animations"

  • privacy.resistFingerprinting;true: Disable google phishing

  • browser.safebrowsing.malware.enabled;false: Disable google malware checking

  • browser.safebrowsing.phishing.enabled;false: Disable google phishing

  • browser.urlbar.speculativeConnect.enabled;false: Disable link prefetch

  • geo.enabled;false: Disable geolocaion

  • network.cookie.lifetimePolicy;2: Only keep cookies this session

  • network.http.referer.trimmingPolicy;2: Only send scheme, host, port in referer

  • network.http.referer.XOriginPolicy;2: Only send referrer in same origin

  • network.http.referer.XOriginTrimmingPolicy;2: Only send scheme, host, port in x-origin referer

  • browser.autofocus: Disable autofocus (useful for VimVixen/Pentadactyl)

  • webgl.disabled;true: Disable WebGL

  • security.dialog_enable_delay;0: Disable addon install delay

  • media.peerconnection.enabled;false: Disable WebRTC

  • extensions.pocket.enabled;false: Disable pocket

Disable Firefox Telemetry

  • toolkit.telemetry.archive.enabled;false: Disable archives

  • toolkit.telemetry.enabled;false: Share less telemetry

  • toolkit.telemetry.rejected;true

  • toolkit.telemetry.server;: Leave blank

  • toolkit.telemetry.unified;false

  • toolkit.telemetry.unifiedIsOptIn;false

  • toolkit.telemetry.prompted;2

  • toolkit.telemetry.rejected;true

Disable sensors

  • device.sensors.ambientLight.enabled;false

  • device.sensors.enabled;false

  • device.sensors.motion.enabled;false

  • device.sensors.orientation.enabled;false

  • device.sensors.proximity.enabled;false

  • dom.battery.enabled;false: Disable battery detection

Startpage with Tridactyl

  • Get PRF_ID from startpage settings

  • Run:

    tridactyl
    set searchurls.spb https://www.startpage.com/do/asearch?prf=PRF_ID&query=
    set searchengine spb

Synergy

This guide will show you how to set up Synergy with ssh encryption and allow you to automatically connect on boot for Mac/Windows/Linux

  • Edit ssh config to allow only one port through

    /etc/ssh/sshd_config
    Match User synergy-user
      GatewayPorts no
      X11Forwarding no
      AllowAgentForwarding no
      PermitTunnel yes
      AllowTcpForwarding yes
      PermitOpen 127.0.0.1:24800
      ForceCommand echo 'pfonly'
      AllowAgentForwarding no
  • Create user

    bash
    sudo useradd -m synergy-user
  • Restart sshd

    bash
    sudo sshd -t && sudo service sshd restart

Mac/Linux

  • Create an ssh key

    bash
    test -f ~/.ssh/id_rsa || ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N ''
  • Copy public key to server

  • Start ssh

    bash
    autossh -M 0 -NL 24800:127.0.0.1:24800 synergy-user@hostname

    or

    bash
    ssh -NL 24800:127.0.0.1:24800 synergy-user@hostname
  • Set Synergy to client mode, with a server address of 127.0.0.1

Windows

  • Create an ssh key with puttygen (from putty website) and save to %HOMEPATH%\Documents\synergy-key.ppk

  • Copy public key to server

  • Download plink (from putty website) to %HOMEPATH%\bin

  • Create startup batch file

    %HOMEPATH%-startup.bat
    %HOMEPATH%\bin\plink.exe -v -i %HOMEPATH%\Documents\synergy-key.ppk -N -L 24800:127.0.0.1:24800 synergy-user@hostname
  • Create shortcut and place in %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup

  • Edit properties of shortcut to run minimized

  • Set Synergy to client mode, with a server address of 127.0.0.1

Scratchpad

  • Windows copy on select http://fy.chalmers.se/~appro/nt/TXMouse/

  • Windows desktop icon save: http://www.softwareok.com/?Download=DesktopOK

  • Better tar

    bash
    tar -Scf /tmp/win7.qcow2.pixz -I pixz win7.qcow2
    progress -mc tar -c pixz
  • Make steam not dumb

    bash
    find ~/.steam/root/ \( -name "libgcc_s.so*" -o -name "libstdc++.so*" -o -name "libxcb.so*" \) -print -delete
  • Possible version remover

    bash
    sed -re 's/^\s*[<>]?=//' -e 's/-r?[0-9.:]+.* / /'
  • Possible fix for tar: Failed to set default locale

    bash
    defaults write org.R-project.R force.LANG en_US.UTF-8

Configure an Apple Router Remotely

  • Run

    bash
    ssh -L 5009:10.0.1.1:5009 user@host
  • Open Airport Utility

  • File > Configure Other > Address: 127.0.0.1

Upload a file

  • To upload, run

    bash
    tar -cf - directory/ | base64 | curl --data-urlencode text@- -d title="File uploaded at $(date '+%d/%h/%y %H:%M:%S') on $(hostname)" -d name=$USER -d expire="1440" https://austen-wares.com/paste/api/create | sed -e 's/view/view\/raw/'
  • To download, run

    bash
    curl https://austen-wares.com/paste/view/raw/ID | base64 -d | tar -xf -

Android wifi

adb shell
settings put global captive_portal_detection_enabled 0

Vbox failing build

  • This is because of strict permissions. To fix

    bash
    sudo chmod -R o+rX /lib/modules /usr/src

Recipes

Chili

A little spicy but extremely delicious

Ingredients

  • 2lb 93-97% lean ground beef

  • 1cup chunky sala - max heat

  • 1can tomato sauce

  • 1can tomato paste

  • 2tsp cumin

  • 2tsp couruander

  • 1tsp cayenne powder

  • 1tsp garlic powder

  • 1tbsp chili powder

  • Chili flakes (opt; for heat)

  • 1can rinsed kidney beans (opt; I dont like them)

Rice

  • 1box chicken broth

  • 3 rice cups of rice

Machines

  • Rice maker

  • Instant pot

Steps

  1. ~20m (1): Brown meat in instant pot on sear &

  2. ~30m (2): Add rice and broth (to 3 line); start rice &

  3. wait 1

  4. Combine all remaining ingredients

  5. Close pot; manual cook 10m &

  6. wait

Templates

Pandas

pandas.py
#!/usr/bin/env python3
import pandas as pd
import numpy as np
# Fix the width
display("text/html", "<style>.container {width:100% !important;}</style>")
# Change options
pd.options.display.float_format = '{:,.10f}'.format
pd.set_option('display.max_colwidth', 500)


# Data loading
df = pd.read_csv('in.csv') # low_memory = False

# Data parsing
df['DATE'] = pd.to_datetime(df['DATE_STR'], format='%Y-%m-%d')
df = df.sort_values(by=['NAME', 'DATE'])
df['DATE_DIFF'] = df.groupby(['NAME'])['DATE'].diff() # .fillna(0)
# Convert to float
df['DATE_DIFF'] = df['DATE_DIFF'].dt.days
# Map
df['NAME'] = df['NAME'].apply(lambda x: x[0] if x[0] == "A" else x[1])

# Filtering
# Extract only some columns
df = df.filter(items = ['COL1', 'COL2'])
# Extract only rows containing string
df = df.filter(like='bbi', axis=0)
# Extract matching regex
df = df.filter(regex='x$', axis=1)
# Run a query
df = df.query('DATE >= 20200101') # Works on dates!

# Aggregation
dfg = df.groupby(['NAME']).agg({
    'DATE_DIFF': ['mean', 'std', 'var', 'count']
    # 'DATE_DIFF': [lambda x: np.std(x, ddof=0), 'std']
})
# From https://queirozf.com/entries/pandas-dataframe-groupby-examples
dfg = df.groupby(['NAME']).apply(
    lambda xdf: xdf.sample(2)
    # lambda xdf: xdf.sort_values(by=['DATE'])
).reset_index(drop=True)
# Bin values
df["VALUE"] = pd.cut(df["VALUE"], 10)
# Bin values (equal size)
df["VALUE"] = pd.qcut(df["VALUE"], 10)

# Pivot tables
df.pivot_table(index="NAME", columns="VALUE", aggfunc=[np.sum, np.mean], fill_value=0)

# Previewing
print(df[df['NAME'] == 'NAME1'][['NAME', 'DATE']])
# Multi-dimensional keys
display(df[('Key1', 'Key2')])
# Display all data
with pd.option_context("display.max_rows", None, "display.max_columns", None):
    display(df)

# Saving
# Excel/ODS
with pdf.ExcelWriter('out.xlsx') as writer:
    df.to_excel(writer, sheet_name='Data') # engine="odf"
    dfg.to_excel(writer, sheet_name='Summary') # engine="odf"
# CSV
df.to_csv('data.csv.gz', compression='gzip')
dfg.to_csv('summary.csv')

# Plotting
df["VALUE"].plot(kind="box")
# Plot with clip
df["VALUE_CLIP"] = df["VALUE"].clip(df["VALUE"].quantile(0.01), df["VALUE"].quantile(0.99))
requirements.txt
pandas
pandas-compat
matplotlib
openpyxl
odfpy

Asciidoc

bash
= wiki
:toc:
:!webfonts:
:source-highlighter: rouge
:rouge-style: molokai

[source,sh,title='bash']
----
----

PlantUML

A basic working PlantUML document with reasonable config

uml.txt
@startuml
' High resolution images
skinparam dpi 300

' Smaller tab size
skinparam tabSize 2

' How should namespaces be separated?
' set namespaceSeparator .
' set namespaceSeparator ::
set namespaceSeparator none

' Hide some circles
hide class circle
hide interface circle

' Hide methods
hide methods
hide stereotype

' Only hide empty
hide empty fields
hide empty attributes

Related -- Related2
Implements --|> Implements2
Composed -* Composed2

package Package {
  enum Enum {
    EL
    EL2
    EL3
  }
  class Class {
    - field: dataType
    - logFunctionName(arg: argType[]):
        \t(tupleEl1, tupleEl2)
    + method(): returnDataType
  }
}
@enduml

To compile with a reasonable file size, run:

sh
PLANTUML_LIMIT_SIZE=8192 plantuml -tpng -oout.png

A reasonable Makefile

Makefile
PLANTUML=DISPLAY= plantuml
SRC=$(wildcard *.txt)
DEST=$(SRC:.txt=.png)
PLANTUML_LIMIT_SIZE=81920

main: $(DEST)

%.png: %.txt
  PLANTUML_LIMIT_SIZE=$(PLANTUML_LIMIT_SIZE) $(PLANTUML) -tpng $^

.PHONY: clean
clean:
  $(RM) $(DEST)

Matplotlib

Preamble

plot.py
import matplotlib.pyplot as plt
fig, ax = plt.subplots()

ax.set_title("Title")

ax.set_xlabel("x")
ax.set_ylabel("y")

ax.plot(data, color="red")

File output

plot.py
fig.savefig(
  "file_name.png",
  transparent=True,   # Transparency,
  dpi=300,            # Good resolution,
  bbox_inches="tight" # Do not clobber axes
)

Greyscale

plot.py
plt.style.use('grayscale')

HTML5

index.html
<!DOCTYPE html>
<html>
    <head>
        <title>T</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
</html

Docker

entrypoint.sh

entrypoint.sh
#!/bin/sh
set -ex

# Should be handled by WORKDIR, but just in case
cd /mnt

# Check if some file exists
[ -e some-file ] || exit 1

# Make sure they are interactive
if [ ! -t 0 ]; then
	printf "Need to open in an interactive terminal\n"
	exit 1
fi

# Check if the file is mounted
if ! mountpoint -q .; then
	printf "Need to mount /mnt first\n"
	exit 2
fi

# Ensure user can write
chown -R user:user .

exec su-exec-static user "$@"

Ubuntu Dockerfile

Dockerfile
# docker run --net=host -it --env="DISPLAY" --volume="$HOME/.Xauthority:/home/user/.Xauthority:rw" riot-web sh
FROM ubuntu:latest
USER root
ARG APT_CACHER_NG_SERVER=192.168.1.214:3142

# Install required packages
# Set proxy if defined
RUN [ "${APT_CACHER_NG_SERVER-}" ] && printf 'Acquire::http:proxy "http://%s";\nAcquire::https::proxy "";\n' "${APT_CACHER_NG_SERVER}" >/etc/apt/apt.conf.d/00proxy

RUN \
    apt-get update              && \
    apt-get full-upgrade -y     && \
    apt-get install -y          && \
    rm -rf /var/lib/apt/lists/* && \
    :

# Delete proxy settings
RUN [ "${APT_CACHER_NG_SERVER}" ] && rm /etc/apt/apt.conf.d/00proxy

RUN useradd -ms /bin/bash user

# COPY . /home/user/

RUN chown user:user /home/user/ # /mnt

WORKDIR /home/user
USER user

Go Dockerfile

Dockerfile
FROM golang:latest

WORKDIR /app/
COPY go.mod go.sum ./
RUN go mod download

COPY ./ ./
RUN go build -o main .

EXPOSE 8080

CMD ["/app/main"]

Alpine/Java Dockerfile

Dockerfile
FROM openjdk:15-alpine

RUN apk add --no-cache su-exec

# COPY . /...

RUN adduser -D user

WORKDIR /mnt

COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["java", "-Xmx4096M", "-Xms4096M", "-Doptions", "-jar", "/jar.jar"]

Docker-compose

docker-compose.yml
version: '3.7'
services:
  svc:
    image: openjdk:latest
    build: ./dir
    # container_name: xxx
    volumes:
      - ./data:/data/:ro
    ports:
      # host:container
      - 192.168.200.222:80:8080
    # command: ps aux
    command:
      - ps
      - aux
    restart: no|always|on-failure|unless-stopped
    # NOTE: docker-compose --compatibility is required for these options
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: '4G'

    build:
      context: ./socat
      dockerfile: Dockerfile2
      # Tag
      image: socat:latest
      args:
        VERSION: 11

Earthly Elixir

build.earth
FROM alpine:latest
WORKDIR /app

RUN adduser -D user
RUN chown -R user:user .

su-exec:
	FROM alpine:latest
	GIT CLONE https://github.com/ncopa/su-exec /su-exec
	RUN apk add --no-cache -U make build-base
	WORKDIR /su-exec
	RUN make su-exec-static

	SAVE ARTIFACT su-exec-static

deps:
	RUN apk add --no-cache --upgrade openssl ncurses-libs

	COPY +su-exec/su-exec-static /usr/bin/su-exec-static

	SAVE IMAGE

build-deps:
	RUN apk add --no-cache --upgrade elixir erlang
	USER user

	ENV MIX_ENV=prod
	RUN mix local.rebar --force
	RUN mix local.hex --force

	COPY --chown user:user mix.exs mix.lock ./
	COPY --chown user:user config config
	RUN mix deps.get --only-prod
	RUN mix deps.compile

	SAVE ARTIFACT /app
	SAVE IMAGE

assets:
	# FROM +build-deps
	RUN apk add --no-cache --update nodejs nodejs-npm
	RUN update-ca-certificates --fresh
	RUN npm i -g npm --no-progress

	USER user
	COPY --chown user:user assets/package.json assets/package-lock.json ./assets/
	COPY --chown user:user +build-deps/app .
	RUN npm ci --prefix ./assets --progress=false --no-audit --loglevel=error

	COPY --chown user:user priv priv
	COPY --chown user:user assets/ assets/
	RUN npm run deploy --prefix ./assets

	SAVE ARTIFACT /app

build:
	FROM +build-deps

	COPY --chown user:user +assets/app .
	RUN mix phx.digest

	COPY --chown user:user lib lib
	# COPY --chown user:user rel rel

	RUN mix do compile, release

	SAVE ARTIFACT /app/_build/prod/rel/elixir_project_ex

docker:
	FROM +deps

	EXPOSE $PORT

	ENV PORT=4000
	ENV HOME=/app

	# Taken care of by entrypoint
	USER root

	COPY --chown nobody:nobody +build/elixir_project_ex .
	COPY --chown nobody:nobody config ./config

	RUN chmod -R a+X .

	COPY ./run.sh ./entrypoint.sh /
	ENTRYPOINT ["/entrypoint.sh"]

	CMD ["./rel/elixir_project_ex/bin/elixir_project_ex", "start"]

	SAVE IMAGE elixir_project_ex

all:
	BUILD +docker

Earthly Go

build.earth
FROM golang:latest
WORKDIR /app

deps:
  COPY go.mod go.sum ./
  RUN go mod download

  SAVE ARTIFACT go.mod AS LOCAL go.mod
  SAVE ARTIFACT go.sum AS LOCAL go.sum
  SAVE IMAGE

build:
  FROM +deps
  COPY go.mod go.sum ./
  RUN go mod download

  COPY ./ ./
  RUN go build -o scrabble-go .

  SAVE ARTIFACT scrabble-go AS LOCAL build/scrabble-go

docker:
  FROM scratch
  BUILD +build
  COPY +build/scrabble-go /
  CMD ["/app/scrabble-go"]
  EXPOSE 8080
  SAVE IMAGE --push registry:5000/scrabble-go:latest

all:
  BUILD +docker

Python

WIP

;

#!/bin/bash
set -euxo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)"
NAME="vm0"
ROOTFS="${SCRIPT_DIR}/${NAME}/main.qcow2"
PORT="3000"
RAM="2G"
CPU="2"
NET=1

OPTS=(
	-enable-kvm
	-cpu host -smp "${CPU}"
	-hda "$ROOTFS"
	-m "${RAM}"
	-name "${NAME}"
	-usb -device usb-tablet
	-monitor stdio
	-device virtio-serial-pci -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent
	-device nec-usb-xhci,id=usb
	-chardev spicevmc,name=usbredir,id=usbredirchardev1
	-device usb-redir,chardev=usbredirchardev1,id=usbredirdev1
	-chardev spicevmc,name=usbredir,id=usbredirchardev2
	-device usb-redir,chardev=usbredirchardev2,id=usbredirdev2
	-chardev spicevmc,name=usbredir,id=usbredirchardev3
	-device usb-redir,chardev=usbredirchardev3,id=usbredirdev3
	-vga qxl
	-spice "ipv4,addr=127.0.0.1,port=${PORT},disable-ticketing"
	# -vnc ":0"
)

((NET)) && OPTS+=(
	-netdev user,id=network0 -device e1000,netdev=network0
)

(($# > 0)) && OPTS+=("${@}")

qemu-system-x86_64 "${OPTS[@]}"

Scripts

Entr

I do not want to install a binary to use entr’s functionality, so I made a shell script that does basically what I want

entr.sh
#!/bin/bash
set -ue
if (( $# < 2 )); then
	echo Wrong usage. entr.sh FILE CMD [CMD_PARAM ...] >&2
	exit 1
fi

case "$(uname)" in
	Darwin)	STAT=(stat -f %m);;
	*)	STAT=(stat -c %Y);;
esac

FNAME="${1}"
shift
LAST_TIME=0
CUURRENT_TIME="$("${STAT[@]}" "${FNAME}")"
while true; do
	if (( LAST_TIME < CUURRENT_TIME )); then
		LAST_TIME="${CUURRENT_TIME}"
		bash -c "${*}"
	fi
	CUURRENT_TIME="${LAST_TIME}"
	sleep .5
done

Snippets

Notify ncdu

F="$(mktemp)"; ncdu -o "${F}" / && tput bel && ncdu -f "${F}"

Bash check numeric

[[ -z "${VAR//[[:digit:]]/}" ]] && echo "Contains only digits"

Perl handle all EOL formats

perl -0pe "s/\\015?\\012/\\n/g; s/x/y/g;"

Loop branches

mapfile -t < <(git branch -r | grep -v '\-> ' | perl -ne 'print if s/^\s*origin\///')
for i in "${MAPFILE[@]}"; do
	printf "Do something %s\n" "${i}"
done

Arg Parser

argparser.sh
read_args() {
	while (($#)); do
		case "${1}" in
			-n|--longopt-no-value)
				SOME_BOOL=1
				shift 1;;
			-w|--longopt-with-value)
				SOME_VALUE="${2}"
				shift 2;;
			-v|--verbose)
				set -x
				shift 1;;
			-h|--help)
				printf "There's no help here\n" >&2
				exit 1;;
			-[w]?*) # All shortops that take a value
				read_args "-${1:1:1}" "${1:2}"
				shift 1;;
			--)
				shift 1
				break;;
			--[:alnum:]*=*|-[:alnum:]=*) # Auto-handle all --? args
				read_args "${1%%=*}" "${1#*=}"
				shift 1;;
			-[:alnum:][:alnum:]*)   # Catches all shortopts that do not take a value
				read_args "-${1:1:1}" "-${1:2}"
				shift 1;;
			*)
				printf "Option %s undefined\n" "${1}" >&2
				exit 2;;
		esac
	done
}
(($#)) && read_args "${@}"

Contributing

If you want to contribute to the wiki, you can make comments on the git project.

Edit: The repo is locked for privacy reasons.