I found this template for Elixir scripts to be really useful:
https://arathunku.com/b/2024/shell-scripting-with-elixir/
To add to that, I wanted to require a particular version of Elixir:
elixir_version_required="~> 1.14"
if not Version.match?(Version.parse!(System.version), Version.parse_requirement!(elixir_version_required)) do
IO.write("Elixir version doesn't match requirement: #{elixir_version_required}")
System.halt(0)
end
Technical Musings
Tools of a technical generalist
Monday, April 22, 2024
Wednesday, December 20, 2017
Export Gnome Extension URLs
To export text list of the URLs of your installed Gnome Extensions:
sudo apt-get install jq
cat ~/.local/share/gnome-shell/extensions/*/metadata.json | jq '.url'
This works for most, but some do not include url in metadata.json.
sudo apt-get install jq
cat ~/.local/share/gnome-shell/extensions/*/metadata.json | jq '.url'
This works for most, but some do not include url in metadata.json.
Friday, March 3, 2017
How To Avoid Taking Down Your S3 With Ansible
The s3 outage summary (https://aws.amazon.com/message/41926/) describing the cause of the outage 2/28/2017, specifically says an 'established playbook' was used to take down s3, which sounds like they used an Ansible playbook. And I'm pretty sure how such a terrible error happened, because I've worked around this problem with Ansible in my own projects.
The normal way you run a subset of a group of servers in Ansible is to add the '--limit' parameter, which filters the list of servers based on a group name. So, of example, you say run on 'web' group with a filter of 'webserver01''; this would only run the Ansible playbook on 'webserver01', not on all the 'web' servers.
The problem is, if you badly specify '--limit' or leave it off, it runs against the whole group. This is a horrible design flaw.
The work around is not to use '--limit' at all, but instead you specify `hosts: "{{ target }}"` in your playbook. So you must specify '-e "target=webserver01' or you get an error saying no hosts specified. The target can be a pattern, so "target=web:database" or "target=webserver0*" works, so this is flexible enough to not need '--limit' at all, and avoid this dangerous design flaw of Ansible.
The normal way you run a subset of a group of servers in Ansible is to add the '--limit' parameter, which filters the list of servers based on a group name. So, of example, you say run on 'web' group with a filter of 'webserver01''; this would only run the Ansible playbook on 'webserver01', not on all the 'web' servers.
The problem is, if you badly specify '--limit' or leave it off, it runs against the whole group. This is a horrible design flaw.
The work around is not to use '--limit' at all, but instead you specify `hosts: "{{ target }}"` in your playbook. So you must specify '-e "target=webserver01' or you get an error saying no hosts specified. The target can be a pattern, so "target=web:database" or "target=webserver0*" works, so this is flexible enough to not need '--limit' at all, and avoid this dangerous design flaw of Ansible.
Tuesday, January 6, 2015
'Compressing' CloudFormation template to get around size limit
Recently I hit the 51,200 byte body size limit of AWS's CloudFormation's templates. I looked into creating Nested Stacks, but that seemed like a pain. Looking at the created json template, I saw a lot of unneeded whitespace.
I used troposhere to generate the template, so it was easy to reduce the size by stripping out the beginning and ending whitespace of each line in the json file.
I just added the following line:
json_compressed="\n".join([line.strip() for line in t.to_json().split("\n")])
utils.validate_cloudformation_template(json_compressed)
This more than havled the size of the template from ~60K to ~25K bytes:
$ wc template.json
1821 2860 60133 template.json
$ wc template_compressed.json
1821 2860 24616 template_compressed.json
And CloudFormation accepted it, no problem.
I used troposhere to generate the template, so it was easy to reduce the size by stripping out the beginning and ending whitespace of each line in the json file.
I just added the following line:
json_compressed="\n".join([line.strip() for line in t.to_json().split("\n")])
utils.validate_cloudformation_template(json_compressed)
This more than havled the size of the template from ~60K to ~25K bytes:
$ wc template.json
1821 2860 60133 template.json
$ wc template_compressed.json
1821 2860 24616 template_compressed.json
And CloudFormation accepted it, no problem.
Friday, January 2, 2015
Elixir Tgraph
In my attempt to learn Elixir, I've converted an Erlang version of a Python script I wrote years ago. It takes a pipe of numeric values and plots lines in a character terminal. Super simple, but handy sometimes.
Now, I know line count is a horrible way to compare code, but here it is:
150 tgraph.py https://gist.github.com/dgulino/4750099
136 tgraph.escript https://gist.github.com/dgulino/4750118
106 tgraph.ex https://gist.github.com/dgulino/298516f7977c57199a4a
The python code is many years old. Maybe I've learned something since then, but I don't write very compactly, on purpose. I only use standard libraries since I don't have the luxury of installing stuff on some of the systems I want to run this on, so can't use some of the cool libraries out there.
It's hard to compare the python code to the Erlang/Elixir.
The Erlang code has added cruft on top to run as Escript (so I don't have to compile changes). I've yet to figure how to enable piping of stdin to Elixir without running a build ('mix escript.build'). So I get to compile my interpreted code!
Otherwise, the Elixir code is easier to read and more concise than Erlang, which is no suprise. Elixir +1.
Now, I know line count is a horrible way to compare code, but here it is:
150 tgraph.py https://gist.github.com/dgulino/4750099
136 tgraph.escript https://gist.github.com/dgulino/4750118
106 tgraph.ex https://gist.github.com/dgulino/298516f7977c57199a4a
The python code is many years old. Maybe I've learned something since then, but I don't write very compactly, on purpose. I only use standard libraries since I don't have the luxury of installing stuff on some of the systems I want to run this on, so can't use some of the cool libraries out there.
It's hard to compare the python code to the Erlang/Elixir.
The Erlang code has added cruft on top to run as Escript (so I don't have to compile changes). I've yet to figure how to enable piping of stdin to Elixir without running a build ('mix escript.build'). So I get to compile my interpreted code!
Otherwise, the Elixir code is easier to read and more concise than Erlang, which is no suprise. Elixir +1.
Friday, November 21, 2014
Number of New Connection Per Second
Under pressure, debuging a production system, given the following question:
"How many new connections per second are we creating to S3?".
My one-liner (Linux):
while true; do diff <(netstat -an | grep ESTAB | grep ":443 "| grep -v "N.N.N.N:443 " | sort) <(sleep 1; netstat -an | grep ESTAB | grep ":443 "| grep -v "N.N.N.N:443 " | sort) | grep "<" | wc -l;sleep 1;done
Where N.N.N.N is the local IP. Many better ways to do this, but I had this in a few minutes.
Done.
"How many new connections per second are we creating to S3?".
My one-liner (Linux):
while true; do diff <(netstat -an | grep ESTAB | grep ":443 "| grep -v "N.N.N.N:443 " | sort) <(sleep 1; netstat -an | grep ESTAB | grep ":443 "| grep -v "N.N.N.N:443 " | sort) | grep "<" | wc -l;sleep 1;done
Where N.N.N.N is the local IP. Many better ways to do this, but I had this in a few minutes.
Done.
Thursday, August 22, 2013
linux mint privacy/security setup
Privacy/Security
Linux(Mint)
dns:
dnscrypt
init.d script
apt-get install sysv-rc-conf
sysv-rc-conf dnsycrypt-proxy on
apt-get install unbound
/etc/unbound/unbound.conf:
forward-zone:
name: "."
forward-addr: 127.0.1.1@53
airplane init.d # cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.0.1
# OpenDNS Fallback (configured by Linux Mint in /etc/resolvconf/resolv.conf.d/tail).
nameserver 208.67.222.222
nameserver 208.67.220.220
disable dnsmasq (not caching):
airplane init.d # cat /etc/NetworkManager/NetworkManager.conf
[main]
plugins=ifupdown,keyfile
#dns=dnsmasq
disabled dnssec in unbound:
# DNSSEC validation using the root trust anchor.
# auto-trust-anchor-file: "/var/lib/unbound/root.key"
mail:
thunderbird/openpgp
http://www.mailvelope.com/
tor:
tor-browser
non-exit relay:
bandwidth limit
secure-delete:
sudo apt-get install secure-delete
srm
password management:
passwordmaker
TODO:
filesystem encryption
#############
android:
apg
#############
firefox:
ghostery
adblock plus (disable reasonable ads)
Linux(Mint)
dns:
dnscrypt
init.d script
apt-get install sysv-rc-conf
sysv-rc-conf dnsycrypt-proxy on
apt-get install unbound
/etc/unbound/unbound.conf:
forward-zone:
name: "."
forward-addr: 127.0.1.1@53
airplane init.d # cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.0.1
# OpenDNS Fallback (configured by Linux Mint in /etc/resolvconf/resolv.conf.d/tail).
nameserver 208.67.222.222
nameserver 208.67.220.220
disable dnsmasq (not caching):
airplane init.d # cat /etc/NetworkManager/NetworkManager.conf
[main]
plugins=ifupdown,keyfile
#dns=dnsmasq
disabled dnssec in unbound:
# DNSSEC validation using the root trust anchor.
# auto-trust-anchor-file: "/var/lib/unbound/root.key"
mail:
thunderbird/openpgp
http://www.mailvelope.com/
tor:
tor-browser
non-exit relay:
bandwidth limit
secure-delete:
sudo apt-get install secure-delete
srm
password management:
passwordmaker
TODO:
filesystem encryption
#############
android:
apg
#############
firefox:
ghostery
adblock plus (disable reasonable ads)
Subscribe to:
Posts (Atom)