- Extra requirement packages can be defined for a python package, using square brackets:
pip install "project[extra]", see https://stackoverflow.com/a/46775606/ - dask is a really cool framework for distributed tasks! For example, one may set an object in shared memory using
.scatter: https://docs.dask.org/en/latest/futures.html#move-data - To uninstall a package installed with pip -e git which gives "No files were found to uninstall", search for a
LIBRARYNAME.egg-linkorLIBRARYNAME.egg-infofile, and rename/delete it; a list of dirs where pip searches when doing a freeze can be found withpython -c 'import sys; print(sys.path)' - Path configuration files can change the python path: https://stackoverflow.com/questions/60338280/
- To test whether a port can be used, bind to the port on all the interfaces; see snippet in the bash section below
- Convert
123MBinto bytes
units = {"KB": 2**10, "MB": 2**20, "GB": 2**30, "TB": 2**40, "PB": 2**50}
def human_to_machine(filesize):
human_unit = filesize[-2:].upper()
if human_unit in units:
return int(filesize[:-2]) * units[human_unit]
else: # if the last two digits are not a unit, it's already in bytes
return int(filesize)Or bytes to human:
IEC_UNITS = {2**0: 'Bi', 2**10: 'Ki', 2**20: 'Mi', 2**30: 'Gi', 2**40: 'Ti', 2**50: 'Pi',
2**60: 'Ei', 2**70: 'Zi', 2**80: 'Yi'}
def b2h(nbytes):
"""Convert from bytes to human-readable powers of 2 amounts (ISO/IEC 80000)"""
if nbytes < 0:
raise ValueError("Number of bytes can't be lower than zero")
for unit, unit_name in IEC_UNITS.items():
if nbytes / unit < 1024: # This means nbytes "fits" in this unit
return nbytes / unit, unit_name
- Reboot/crash-safe locking mechanism for single Linux box:
def get_lock():
"""Use a socket as a clean lock on the application. stackoverflow.com/a/7758075"""
# Hold reference to our socket somewhere or it gets garbage collected at function exit.
get_lock._lock_socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
# Any placeholder here is fine.
process_name = "my application name"
try:
# The null byte (\0) prefix means the socket is created in the abstract namespace instead
# of being created on the file system itself; Linux only feature.
get_lock._lock_socket.bind("\0" + process_name)
except socket.error:
# Here handle case of another instance of this application running- Basic logging config
import logging
_INFO = "\033[92m" # GREEN
_WARNING = "\033[93m" # YELLOW
_ERROR = "\033[91m" # RED
_RESET = "\033[0m" # RESET
logging.basicConfig(format="{asctime} [{levelname}] {message}", style="{", level=logging.INFO)
logging.addLevelName(logging.INFO, _INFO + logging.getLevelName(logging.INFO) + _RESET)
logging.addLevelName(logging.WARNING, _WARNING + logging.getLevelName(logging.WARNING) + _RESET)
logging.addLevelName(logging.ERROR, _ERROR + logging.getLevelName(logging.ERROR) + _RESET)
def _quit(*vargs, **kwargs):
logging.error(*vargs, **kwargs)
raise SystemExit
logging.quit = _quit- Extract MX records and select highest priority using
host(frombind-utilspackage on RPM):
import subprocess as sp
def mx_to_smtp(domain):
"""Extract SMTP server with highest priority from MX record of argument `domain`."""
try:
# host is part of bind-utils on RHEL, but it should be almost universal.
cmd = ("host", "-t", "MX", domain)
proc = sp.run(cmd, stdout=sp.PIPE, stderr=sp.PIPE, check=True)
except sp.CalledProcessError as exc:
logging.quit("Error while extracting SMTP hosts from domain '%s', error %s - %s",
domain, exc, exc.stderr.decode("utf-8").strip().replace("\n", "|"))
prior_host = [line.split()[-2:] for line in proc.stdout.decode("utf-8").strip().split("\n")]
_, hostname = sorted(prior_host, key=lambda pair: int(pair[0]))[0]
return hostname.strip(".")- Send email function
import smtplib
from email.message import EmailMessage
def send_email(body, subject, recipients, email_from, smtp_server, smtp_port):
msg = EmailMessage()
msg.set_content(body)
msg["Subject"] = subject
msg["From"] = email_from
msg["To"] = recipients
logging.info("Opening connection to smpt server '%s:%s'", smtp_server, smtp_port)
with smtplib.SMTP(smtp_server, port=smtp_port) as smtp:
logging.info("Sending email to '%s'", recipients)
# The output of .send_message is a dict with an entry for each recipient that failed.
return smtp.send_message(msg)- Test if a port is available by binding to it on all the interfaces (
0.0.0.0); Python 2.7,3+ needed; thanks to @afrighetto:
# If no return is present, the last command exitcode is returned.
function is_port_avail() {{
python - <<'EOF' $1
import sys, errno, socket
from contextlib import closing
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
s.bind(("0.0.0.0", int(sys.argv[1])))
sys.exit(0) # 0 is True==available in Unix, 1 is False==already taken
except socket.error as e:
sys.exit(1)
EOF
}}
is_port_avail 1234 && run_server 1234- print all text to screen, while saving only certain text to file; useful if debug is too verbose to be stored, but still useful to be seen in the window of a
screensession (|&==2>&1 |):
$ echo -e "INFO: ciao\nDEBUG:buh\nDEBUG:asfasd\nINFO: asdfaasdfad" |& tee /dev/tty | grep -v DEBUG > /info.log
INFO: ciao
DEBUG:buh
DEBUG:asfasd
INFO: asdfaasdfad
$ cat /tmp/info.log
INFO: ciao
INFO: asdfaasdfad
- spawn a single ssh agent and recycle agent process details between sessions; add to your
~/.bashrc:
# Spawn an ssh agent if not running, and save details to reuse it.
ssh-add -l &>/dev/null
if [ "$?" == 2 ]; then
# Could not open a connection to your authentication agent.
# Load stored agent connection info.
test -r ~/.ssh-agent && \
eval "$(<~/.ssh-agent)" >/dev/null
ssh-add -l &>/dev/null
if [ "$?" == 2 ]; then
# Start agent and store agent connection info.
(umask 066; ssh-agent > ~/.ssh-agent)
eval "$(<~/.ssh-agent)" >/dev/null
fi
fi-
Generic intros to k8s:
-
Pod: 1+ containers. 99% of times it's a single container; there may be cases where multiple containers may need to go hand-in-hand inside a pod, to form a single micro-service.
-
Service: expose a pod/container to the cluster or the external world, using things like
ClusterIP,NodePort,LoadBalancer, etc; all these services need to specify certain parameters:portis the one exposed to the rest of the cluster;targetPortis the one that the application inside the container listens to (could it be also set using ConfigMaps?);nodePortopens a port on the physical server the container is running on (ifNodePortservice is defined, but nonodePortparam, random # in range:30000-32767);
-
Resources: "requests" set the minimum amount of resources to allocate, while "limits" specify the maximum amount of resources that the pod/container can reach during runtime. It's important to set requests on containers, otherwise k8s will use the limit as a request, and it'll try to allocate the pod on a node using the limit; so always set a minimum amount in requests, to improve pod allocation scheduling
-
Resources: setting a low amount of memory on a container may cause it to be OOM-Killed (see it with
kubectl describe pod _pod_name_), but setting a low amount of cpu share will just slow down the pod execution, and won't cause any error (because CPU is a compressible resource). See: https://medium.com/@betz.mark/understanding-resource-limits-in-kubernetes-cpu-time-9eff74d3161b -
labels:
.metadata.labelsare labels related to the object being defined (the deployment, the service, etc);.spec.selector.matchLabelsor.spec.selectorneed to point to the objects we want to reference, and have to be identical to.spec.template.metadata.labels; https://medium.com/@zwhitchcox/matchlabels-labels-and-selectors-explained-in-detail-for-beginners-d421bdd05362 -
Storage: a persistent volume (pv) is the base "unit" of storage; it can by manually created, but the best thing to do is letting k8s manage them, through persistent volume claims (pvc). PVC are pieces of software that connect PV to pods; a pod does not directly ask for a specific PV, but let the PVC claim it from a storage class object (can a storage class be set as default?)
-
kubectl diff -f depl.yamlreports the difference between the current status of the system and the one requested indepl.yaml -
Make sure to wait for all components to be deleted before reinstalling a helm chart, or the new installation may find leftover components that are being deleted and not recreate them:
helm uninstall this; sleep 1m; helm install --debug --wait this -
Run pod on-the-fly:
kubectl -n mysql-shell run temp-mysql-shell --image=mysql:5 --command -- sh -c 'sleep infinity' -
Create secret from cmdline:
read -sp "Registry password: " HUB_PASSWORD; kubectl -n namespacehere create secret docker-registry reg-creds --docker-server=hub.example.org --docker-username="myuser@example.org" --docker-password=${HUB_PASSWORD} -
To add a new TLS certificate to k8s behind a AWS Load Balancer, go to EC2 > Load Balancer > select the one connected to the k8s cluster > click on the https:443 listener > in the new window, choose the Certificates tab > Add a new one > Select the new one. Alternatively, you can set the new one as a new default, if it covers also domains previously covered by the older certificate.
-
Environment variables need to be expanded with
$(variable)rather than${variable}when passed as arguments to an entrypoint, see docs. -
kustomize helm inflator: the
valuesMergefield only applies tovaluesInline, not toadditionalValuesFileswhich is always merged on top ofvaluesFile/valuesInline -
kubectl diff(and argocd, which uses it) can't tell if a ConfigMap got extra values in it, see here
[alberto@fedora]$ cat cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: albertotest
data:
var1: "a value"
[alberto@fedora]$ k apply -f cm.yaml
[alberto@fedora]$ k edit cm/albertotest
[alberto@fedora]$ k get cm/albertotest -o yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: albertotest
data:
var1: a value
var2: another value
[alberto@fedora]$ k diff -f cm.yaml
[alberto@fedora]$- awscli pod using a
ServiceAccountto debug:
apiVersion: v1
kind: Pod
metadata:
name: awscli
spec:
containers:
- image: amazon/aws-cli
name: awscli
command:
- /bin/sh
- -c
- sleep 1d
serviceAccountName: XXX- k8s does an interpolation of env vars defined in the
command/argsfields when the variables are wrapped in$():
apiVersion: v1
kind: Pod
metadata:
name: ubuntu
spec:
containers:
- image: ubuntu
command:
- /bin/bash
args:
- -c
- 'echo "hostname: $(HOSTNAME), pod name: $(POD_NAME)"'
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.nameWhen running the pod you can see
$ k logs pod/ubuntu
/bin/bash: line 1: HOSTNAME: command not found
hostname: , pod name: ubuntuThe error on the first line is because k8s didn't replace HOSTNAME as it didn't find it among the env vars, so it gets passed into Bash, which tries to execute it as a command and fails.
Also, interpolation between different env vars is possible, but the ordering is important. The following envs will populate JAVA_OPTS like you'd expect, while inverting the order will not work and you'll see bash try to execute the POD_NAME command:
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: JAVA_OPTS
value: "here are some java $(POD_NAME) options"- mount the root of an EFS share on a pod to check its content
Details
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: efs-pv-test
spec:
capacity:
storage: 1Gi
volumeMode: Filesystem
storageClassName: efs-sc
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
csi:
driver: efs.csi.aws.com
volumeHandle: "fs-0123456789" # <---------- replace this
# mountOptions can be set here if needed:
# volumeAttributes:
# directoryPerms: "0777"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: efs-pvc-test
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
volumeName: efs-pv-test
storageClassName: efs-sc
---
apiVersion: v1
kind: Pod
metadata:
name: efs-inspect
spec:
containers:
- name: shell
image: ubuntu
command: ["/bin/sh","-c"]
args:
- "sleep 1d"
volumeMounts:
- name: efs-vol
mountPath: /efs
restartPolicy: Never
volumes:
- name: efs-vol
persistentVolumeClaim:
claimName: efs-pvc-test- mount lustre (fsx for lustre) on a k8s pod. Setup a pod with the following manifest, then in it install the client
dnf install -y lustre-clientand mount the fs:
Details
apiVersion: v1
kind: Pod
metadata:
name: fsx-inspect
spec:
containers:
- name: shell
image: amazonlinux:2023
command: ["/bin/sh","-c"]
args: ["sleep 1d"]
securityContext:
# not sure which of the following two is actually needed
privileged: true
capabilities:
add: ["ALL"]
restartPolicy: Never
- http://codeflex.co/what-is-apache-kafka/
- https://stackoverflow.com/a/48666220/
- A consumer group consuming from many partitions is the way to achieve parallelism.
- The implicit return (similar to Ruby or R) is tricky at first
- The scope creator
{}can be used "inline" as an expression: https://doc.rust-lang.org/stable/book/ch03-03-how-functions-work.html#function-bodies-contain-statements-and-expressions
- Location directives need to be in reverse order of relevance, first /, then /app: https://serverfault.com/a/391488
- Multiple rewrite conditions can be set up following the scheme
RewriteCond X \n RewriteCond Y \n RewriteRule Zand then again[Cond]+ Rule - To proxy websockets along with http(s):
<VirtualHost *:80>
RewriteEngine On
# Maybe not useful, as many app directly open wss://
RewriteCond %{HTTP:UPGRADE} =websocket [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade [NC]
RewriteRule ^/?(.*) wss://%{SERVER_NAME}/$1 [P]
# Redirect to HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [END,NE,R=permanent]
</VirtualHost>
<VirtualHost *:443>
RewriteEngine On
RewriteCond %{HTTP:UPGRADE} =websocket [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade [NC]
RewriteRule ^/?(.*) ws://backend:5678/$1 [P]
# Always redirect to www. version
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^/?(.*) https://www.%{SERVER_NAME}/$1 [END,NE,R=permanent]
# From least specific (/) to more specific (/app)
<Location />
# default site config/proxypass
</Location>
<Location /app>
ProxyPass http://backend:5678/app
ProxyPassReverse http://backend:5678/app
</Location>
</VirtualHost>
- SLURM cores/tasks/cpus explanation: https://stackoverflow.com/questions/51139711/hpc-cluster-select-the-number-of-cpus-and-threads-in-slurm-sbatch
- useful squeue long options to set as alias of squeue:
squeue -o "%.18i %.9P %.8j %.8u %.8T %.10M %.9l %.5C %.8m %.6D %R" - MPI hello world
Compile with#include <mpi.h> #include <stdio.h> int main(int argc, char **argv) { // Initialize the MPI environment MPI_Init(NULL, NULL); // Get the number of processes int world_size; MPI_Comm_size(MPI_COMM_WORLD, &world_size); // Get the rank of the process int world_rank; MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); // Get the name of the processor char processor_name[MPI_MAX_PROCESSOR_NAME]; int name_len; MPI_Get_processor_name(processor_name, &name_len); // Print off a hello world message printf("Hello world from processor %s, rank %d out of %d processors\n", processor_name, world_rank, world_size); // Finalize the MPI environment. MPI_Finalize(); }mpicc helloworld.c -o helloworld.xand run with ampirun --map-by node helloworld.xin a script submitted withsbatch --ntasks-per-node=2 --ntasks 4 helloworld.sh(the--map-by nodeis important otherwise the mpi context doesn't see all processors in the job correctly, docs).
- Download a m3u8 playlist, using only FFmpeg:
ffmpeg -i "https://example.com/playlist.m3u8" -codec copy output.mp4
- To crop a person out of a picture to a 512x512 px image with 5 px white border (e.g. Telegram stickers):
- Tools > Selection Tools > Intelligent Scissors [I]
- Connect all the points around the image until you close the loop; click inside it to convert it to a selection
- Layer > Transparency > Add Alpha Channel
- Select > Invert [Ctrl+I]
- Edit > Clear [Delete]
- Image > Crop to content
- Image > Scale Image > 502 px on the larger of the two axes
- Image > Canvas size > 512 px to both axes > Center
- Select > None [Ctrl+Shift+A]
- Layer > Transparency > Alpha to Selection
- Layer > New Layer [Ctrl+Shift+N] > Transparency
- Move the empty layer below the one with the cropped image
- Select > Border > 5 px
- Edit > Fill with FG Color (should be white)
- File > Export as > Name the file with .png to preserve the transparency
'NoneType' object is not iterableon a simple ping of a server (ansible 2.9); delete the cache file incache.d/${SERVER}- Transform nested dicts in set_facts (no
with_items/loop?) using jinja2. E.g. given the following in conf.yaml:
users:
user1:
name: Ajeje Brazov
user2:
name: Antani Coso
user3:
name: Tizio Caioto obtain the following:
set_fact:
sublist_users:
- nick: user1
name: Ajeje Brazov
- nick: user3
name: Tizio Caiouse this jinja snippet:
set_fact:
sublist_users: |
{% set list_users = [] -%}
{% for _user in ['user1', 'user3', ] -%}
{% set _ = list_users.append({'nick': _user, 'name': users[_user].name}) -%}
{%- endfor %}
{{ list_users }}- Load a file/template into a ansible variable, differentiating by distro, with fallback to generic file/template:
- name: If variable_to_load_into is undefined, load it from file
set_fact:
variable_to_load_into: '{{ lookup("template", item) }}'
with_first_found:
- '../templates/{{ "progr-config-" ~ progr_release ~ "-" ~ ansible_os_family ~ ".cfg.j2" }}'
- '../templates/{{ "progr-config-" ~ progr_release ~ ".cfg.j2" }}'
- '../templates/progr-config.cfg.j2'
when: variable_to_load_into is not definedif you want to avoid template parsing change the set_fact with variable_to_load_into: '{{ lookup("file", item) }}'. This tries to load ../templates/progr-config-123.456-RedHat.cfg.j2 first, fallbacking to ../templates/progr-config-123.456.cfg.j2 and finally to ../templates/progr-config.cfg.j2.
- To "take track" of a long-running shell command, add a
|& tee /dev/shm/job_$(date -u +"%Y-%m-%dT%H-%M").logat the end of the shell command.
- When restarting
systemd-tmpfiles-setup, make sure to restart alsosystemd-user-sessions, otherwise/run/nologinis created and non-root users can't login. - To mask a service under
/etc/systemd/system/you need to first remove the service manually
- To clear all the layers added to a map except for the "basic" layer (e.g. the OSM satellite tiles), use:
while (Object.keys(mymap._layers).length > 1) { mymap.removeLayer(mymap._layers[Object.keys(mymap._layers)[1]]); }Install unison 2.51.2 on Ubuntu 16.04:
$ wget https://github.com/ocaml/opam/releases/download/2.1.0-alpha/opam-2.1.0-alpha-x86_64-linux
$ chmod +x opam-2.1.0-alpha-x86_64-linux
$ mv ./opam-2.1.0-alpha-x86_64-linux ~/bin/ # Move the opam binary into one of the $PATH dirs
$ ln -s opam-2.1.0-alpha-x86_64-linux ~/bin/opam
$ mkdir temp_bubblewrap && cd temp_bubblewrap
$ wget http://security.ubuntu.com/ubuntu/pool/main/b/bubblewrap/bubblewrap_0.2.1-1ubuntu0.1_amd64.deb
$ ar x bubblewrap_0.2.1-1ubuntu0.1_amd64.deb
$ tar xf data.tar.xz ./usr/bin/bwrap
$ mv usr/bin/bwrap ~/bin/ # Move the bwrap binary into one of the $PATH dirs
$ opam switch create 4.08.1
$ eval $(opam env --switch=4.08.1)
$ wget https://github.com/bcpierce00/unison/archive/v2.51.2.tar.gz
$ mv {v,unison-}2.51.2.tar.gz
$ tar -xf unison-2.51.2.tar.gz
$ cd unison-2.51.2/
$ wget https://git.archlinux.org/svntogit/packages.git/plain/trunk/4.08-compatibility.patch?h=packages/unison
$ mv 4.08-compatibility.patch\?h\=packages%2Funison unison-ocaml-4.08.patch
$ patch -p1 <unison-ocaml-4.08.patch
$ make
# mv src/unison /usr/bin/unison-2.51-ocaml-4.08.1
# ln -s unison-2.51 /usr/bin/unison-2.51.2- To show all compiler and linker options:
cc -v -craype-verbose
- Show chain of certificates in file:
$ openssl crl2pkcs7 -nocrl -certfile certificate_file.pem | openssl pkcs7 -print_certs -noout
subject=/C=YourCountryHere/ST=YourStateHere/O=Your Organization Name Here/OU=Self-Enrolled/CN=common.name.here.example.com
issuer=/C=US/ST=MI/L=Ann Arbor/O=Internet2/OU=InCommon/CN=InCommon RSA Server CA
subject=/C=US/ST=MI/L=Ann Arbor/O=Internet2/OU=InCommon/CN=InCommon RSA Server CA
issuer=/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority
subject=/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=Comodo CA Limited/CN=AAA Certificate Services
Make sure to order certificates in the order requested by your application. Nginx requires the most local certificate to be specified first, then the intermediate certificates following. The issuer of a certificate should match with the subject of the line below. You should drop the root certificate (the one where the subject matches the issuer) to reduce trust chain issues.
- Check modulus of certificate and private key for them to match (only the first certificate is used, so ordering matters)
$ openssl rsa -modulus -noout -in website.key |openssl md5
(stdin)= 1234567890
$ openssl x509 -modulus -noout -in website.cert |openssl md5
(stdin)= 1234567890
- Add a debug block to print the content of the
githubcontext variable- name: Debug GH context run: echo "$GITHUB_CONTEXT" env: GITHUB_CONTEXT: ${{ toJson(github) }}
- To make podman look for unqualified (without hostname) images in Docker Hub, set
unqualified-search-registries = ["docker.io"]in/etc/containers/registries.conf.
- To add "static" labels to all metrics collected by prometheus without having to relabel and mess with
scrape_configs,relabel_configs, etc and without having to relabel metrics coming from other sources, e.g.kube-pod-infofromkube-state-metrics, you can useserver.global.external_labelsas shown in this example, even though it's not documented in the chart'svalues.yamlfile
- always create RDS clusters with corresponding custom parameter groups
- parallelcluster
- Set
HeadNode.Networking.ElasticIp: trueto automatically assign an ip to a head node configured with public subnets, so you can ssh into it. - Make sure to leave some room to the head node instance, as there are some init scripts that can consume more than 1.5 GB of ram. This may manifest as head nodes that keep getting created and destroyed over and over. When checking
/var/log/cfn-init.logand/var/log/chef-client.logon the node you may see something like the following:
This is because Amazon Linux 2023 (================================================================================ Error executing action `run` on resource 'bash[Backup /opt/intel]' ================================================================================ Mixlib::ShellOut::ShellCommandFailed ------------------------------------ Expected process to exit with [0], but received '11' ---- Begin output of "bash" ---- STDOUT: STDERR: rsync: [receiver] write failed on "/tmp/opt/intel/packagemanager/1.0/packagemanager": No space left on device (28) rsync error: error in file IO (code 11) at receiver.c(381) [receiver=3.4.0] rsync: [sender] write error: Broken pipe (32)alinux2023) automatically assigns 50% of the available RAM to the/tmpfolder, so pick an instance with at least 4 GB of RAM.
- Set
sknil_cstl_swodniw/ved.evargssam//:sptth
- create a user and make it owner of a db
$ PGPASSWORD=*** psql -h db -U adminuserhere postgres postgres=> create user usernamehere with password '***'; postgres=> grant all on database databasehere to usernamehere; postgres=> \c databasehere databasehere=> grant all on schema public to usernamehere; $ PGPASSWORD=*** psql -U usernamehere databasehere -h db databasehere=> create table t(i integer); databasehere=> drop table t;
- create a user and make it owner of a db
$ mysql -h db -uadminuserhere -p'***' mysql mysql> create database databasehere; mysql> create user usernamehere identified by '****'; mysql> grant all privileges on databasehere.* to 'usernamehere' with grant option;
To test if a port is available on all the interfaces you can do:
! ncat -z -w 1 0.0.0.0 ${port} && ! ncat -z -w 1 :: ${port} && runserver ${port}possibly omitting the part for IPv4 or IPv6 if you don't use IPv4 or IPv6