2025-09-24

Cuál es la allowlist?

Desde hace unos meses estoy usando cursor, el IDE, para programar. Como parte de ese uso, cuando hablo con las IAs, las mismas intentan correr comandos. Como es peligroso, uno tiene que andar aprobando cada comando. Pero como es engorroso, es posible whitelistear comandos para que corran sin preguntar (en este momento estoy usando la versión 1.6.45 en mac). El problema es que no pude encontrar en la GUI de cursor como ver/editar dichos comandos. Así que estuve usando el chat de cursor para encontrar los comandos que whitelistié y después de un ratito los encontramos :D. 
Para ver los comandos que tengo whitelisteados tengo que correr este comando:

% sqlite3 -noheader -list "$HOME/Library/Application Support/Cursor/User/globalStorage/state.vscdb" "SELECT je.value FROM ItemTable AS it, json_each(it.value, '$.composerState.yoloCommandAllowlist') AS je WHERE it.key='src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser';"

diff

jq

grep

head

cd

git log

git diff

git show

npm audit

sed

awk

cat

echo

Seguramente si estás en una mac el mismo comando te ande a vos

dDesde hace unos meses estoy usando cursor, el IDE, para programar. Como parte de ese uso, cuando hablo con las IAs, las mismas intentan correr comandos. Como es peligroso, uno tiene que andar aprobando cada comando. 

Y haciendo esto me di cuenta que aprobé comandos complicados :/. sed y awk tienen la opción de editar archivos inline.

Para sacarlos tuve que salir de cursor y correr este comando (que reescribe toda la lista del whitelist):

% sqlite3 "$HOME/Library/Application Support/Cursor/User/globalStorage/state.vscdb" \

"UPDATE ItemTable SET value = json_set(value, '$.composerState.yoloCommandAllowlist', json('[\"diff\",\"jq\",\"grep\",\"head\",\"cd\",\"git log\",\"git diff\",\"git show\",\"npm audit\",\"cat\",\"echo\"]')) WHERE key='src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser';"

Y después corrí esto para ver que quedó bien:

% sqlite3 -noheader -list "$HOME/Library/Application Support/Cursor/User/globalStorage/state.vscdb" \

"SELECT je.value FROM ItemTable AS it, json_each(it.value, '$.composerState.yoloCommandAllowlist') AS je WHERE it.key='src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser';" 

Por último pedí en el chat que corra sed para ver que está todo bien :)

Esto me lleva a ver que cursor, el IDE, está super verde y pushean features que les faltan cosas. ¡Es un peligro!

PD: Es peor! Si la allowlist está activada puede correr comandos usando redirección de shell (>) y escribir sin confirmación del usuario. Por lo tanto hay que desactivarla hasta que arreglen esto. Para hacer esto podés ir a cmd-shift-p -> Cursor Settings -> Chat -> Auto-Run -> Auto-Run Mode y setear en Ask Every Time. 

2025-07-01

Tuneando firefox sobre ssh

Hace un tiempo hice que Firefox corra remoto sobre X. Para eso forwardeo el X por ssh (haciendo $ ssh -X blah) Y esto anda bien para correr sobre una VM. Pero cuando probé conectarme a mi linux desde mi mac no anduvo :(. Así que primero tuve que decirle como forwardear XAuthority corriendo XAUTHORITY=$HOME/.Xauthority firefox --no-remote. Pero cuando quiero conectarme a otra compu en mi red wifi anda muy lento. Así que hice algunas optimizaciones.

La primera es que cuando me conecto por ssh le paso -C para que comprima los datos, porque X manda bocha de cosas para forwardear la pantalla. Y el otro seteo que sirvió para algo fue ir a about:config en firefox y bajar el frame rate seteando layout.frame_rate en 15.

Con eso puedo usar firefox más o menos. Una cosa medio molesta es que el audio sigue saliendo por los parlantes de mi linux y no encontré fácil como forwardearlo o mutearlo, pero aunque sea así es posible usar firefox forwardeado por X por mi wifi, así que ese arreglo quedará para el futuro.

2025-05-14

pingmon update

Hace un tiempo hice un script para monitorear mi conexión a internet usando ping. 

Le hice algunos cambios menores, y ahora muestra datos aunque no haya llenado toda la ventana.

Esta es la última versión

#!/usr/bin/env python3

import subprocess
import sys
import re

SEQ_NUMBER_RE = re.compile(r".*icmp_seq=(\d+) ttl.*")

def report(probes, count):
  if len(probes) < count:
    count = len(probes)
  return str ( count - sum(probes[-count:]) ) 

def monitor(ip):
  probes = []
  ping = subprocess.Popen(["ping", ip], stdout=subprocess.PIPE)
  stdout = ping.stdout

  stdout.readline() # Ignore first line
  line_count = 0
  last_seq_number = 0
  while True:
    line_count +=1
    line = stdout.readline().decode()
    try:
      seq_number = int( SEQ_NUMBER_RE.match(line).group(1))
    except Exception:
      print( "!!! Failed while parsing line " + line )
      seq_number = last_seq_number
    probes.extend([0] * (seq_number - last_seq_number - 1))
    probes.append(1)
    print( "(%s) 10:%s 100:%s 1000:%s 10000:%s" % (
      line_count, report(probes, 10), report(probes, 100), report(probes, 1000), report(probes, 10000)
    ) )

    probes = probes[-10000:] # Keep memory usage bounded
    last_seq_number = seq_number

def main(argv):
  monitor(argv[1])

if __name__ == '__main__':
  main(sys.argv)

2024-11-09

Sobre vacas y pampas

¡Qué fea que es la vegetación nativa de las pampas! Toda dura, con pinches, casi sin árboles. ¿Por qué es así? ¿Siempre fue así?

¿Será culpa de los españoles? Ellos soltaron vacas en las pampas. Las vacas se reprodujeron un montón porque no hay animales que las puedan comer en la pampas. ¿Sabemos cómo eran las pampas antes de las vacas? ¿Hay alguna historia transmitida oralmente por los pueblos originarios? ¿Hay algún estudio serio? ¿Dónde está el paper con referato que lo estudie?

Yo creo que lo que conocemos de la vegetación nativa de las pampas es lo que sobrevivió a las vacas, que se comieron todo a su paso mientras explotaron poblacionalmente en las pampas por varios siglos, hasta que la campaña de Roca terminó de conquistar la zona. Por eso es todo pinchudo y duro.

Restauremos las pampas. Plantemos árboles, plantemos pastos blanditos. La vegetación no tiene que lastimarnos.



2024-09-05

heic a jpg

Estoy en ubuntu, me conecto al celu y las fotos están en formato .heic ¯_(ツ)_/¯. Pero quiero un .jpg! Ah! Ya sé, googleo y encuentro esto. Para convertir un montón de archivos .heic a .jpg hay que instalar libheif-examples en la consola así:

$ sudo apt-get install libheif-examples

Y después se puede correr esto:

$ for file in *.heic; do heif-convert $file ${file/%.heic/.jpg}; done

Para convertir todos los .heic de un directorio.

Ajustalo si querés hacer otra cosa.

2023-08-08

Lubuntu sin GUI

Ayer a la noche arranco mi notebook, que tiene instalado lubuntu 22.04, y en vez de abrir la GUI de siempre me abre la terminal en texto. Por suerte se sigue conectando al wifi. Así que podía instalar cosas en línea de comando. Cuando rebooteo veo que por un momento aparece el error ACPI BIOS Error (bug): Could not resolve symbol [\CTDP]. 

Después de tratar de tocar grub para que bootee distinto, infructuosamente, encontré una guía para instalar guis en ubuntu. En ella dice que la forma más fácil para instalar una gui es usar la utilidad tasksel, y que puedo instalar la gui de lubuntu con eso, instalando la gui lxqt. Así que hice sudo apt install tasksel, sudo tasksel, elegí lxqt, esperé a que termine, rebootié, y ahora tengo gui de nuevo!

2023-01-27

Aceptar invites a repos de github desde línea de comando

Si por algún motivo querés aceptar invites a repos desde línea de comando en github, se puede!

Para hacer eso, hay que usar el comando gh y tener estar autenticado via 

$ gh auth login

Una vez que estás autenticado, hay que usar el api de github directamente via gh api, que maneja la autenticación por nosotros y recibe parámetros de forma análoga a curl.

El comando para obtener todos los invites pendientes es:

$ gh api user/repository_invitations

y devuelve un array con todas las invitaciones pendientes del usuario (en json).

Lo importante de ese array es que cada entrada tiene un campo "id". Es algo así:

[
  {
    "id": 12345678,
    "repository": {
      "full_name": "usuario/repo",
      "otras": "cosas",
    },
    "otras": "cosas"
  },
  { "id": "23456789", "otras": "cosas" }
]

Con ese id, podés correr este otro comando para aceptar el invite así:

$ gh api -X PATCH user/repository_invitations/12345678

y si salió todo bien ahora podés hacer clone de ese repo privado así:

$ gh repo clone usuario/repo 

Espero que les sirva!

PD: Las llamadas a la API las deduje de acá.

2022-09-21

estimate-sol

Hoy publiqué una herramienta open-source que sirve para medir el tamaño de contratos de solidity. Está en pypi, y podés instalarla corriendo pip install estimate-sol. Este es el uso:

$ estimate-sol -h
usage: estimate-sol [-h] [--punctuations] [--encoding ENCODING] [--dependencies-multiplier DEPENDENCIES_MULTIPLIER]
[--assembly-multiplier ASSEMBLY_MULTIPLIER] [--week-size WEEK_SIZE] [-a] [-V]
files [files ...]

Estimate solidity audit sizes.

positional arguments:
files Files to be audited.

optional arguments:
-h, --help show this help message and exit
--punctuations, -p Use punctuations for counting (default: lines)
--encoding ENCODING, -e ENCODING
File encoding (default=utf-8).
--dependencies-multiplier DEPENDENCIES_MULTIPLIER, -d DEPENDENCIES_MULTIPLIER
Multiplier to estimate non-audited dependencies (default=1.0).
--assembly-multiplier ASSEMBLY_MULTIPLIER
Multiplier to estimate assembly code (default=1.0).
--week-size WEEK_SIZE, -w WEEK_SIZE
Number of items to audit per week. Defaults: (lines:1.0, punct:1.0)
-a, --absolute_paths Show all paths as absolute (by default relative paths are shown if inside current directory).
-V, --version show program's version number and exit
Y podés ver el anuncio original acá.

2022-09-09

chromium en snap via ssh

Me conecto a una VM por ssh, forwardeando X (ssh -X).

Instalo el snap de chromium (sudo snap install chromium).

Lo corro, y me da este error.

$ chromium
X11 connection rejected because of wrong authentication.
[2050513:2050513:0909/155104.874445:ERROR:ozone_platform_x11.cc(240)] Missing X server or $DISPLAY
[2050513:2050513:0909/155104.874518:ERROR:env.cc(255)] The platform failed to initialize.  Exiting.
[1]+  Done                    XAUTHORITY=$HOME/.Xauthority chromium

Para arreglar el problema hay que setearle la variable de entorno de XAUTHORITY (¿por qué?).

Lo corro así y problema solucionado.

$ XAUTHORITY=$HOME/.Xauthority chromium

2022-08-28

ssh-agent no anda en lubuntu 22.4

Este fin de semana upgradié el sistema operativo de mi notebook. Lo pasé de lubuntu 20.4 a lubuntu 22.4.1. Cuando terminé todo anduvo razonablemente bien (booteó!) pero el agente de ssh dejó de arrancar solo.
Estuve un rato googleando y no encontraba nada. Así que me puse a buscar como arranca el ssh-agent. Para eso tiré un find con un grep en mi home.
 
$ find . -type f -print0 | xargs -0 -n 1000 fgrep -n ssh-agent
 
Hice eso y encontré que en el archivo $HOME/.xsession-errors tenía este mensaje de error:
 
/etc/X11/Xsession.d/90x11-common_ssh-agent: line 9: has_option: command not found
 
¡Bingo!
Googlié el error y encontré este reporte de bug de ubuntu. Dentro de los comentarios encontré la solución.
La misma consiste en poner en el directorio /etc/X11/Xsession.d/ un archivo más para definir has_option. El archivo yo lo nombré 01x11-has_option-aure y tiene este contenido:
 
# This file is sourced by Xsession(5), not executed.
#
# workaround created by Settel
# defines "has_option" unless it is already defined
# see https://bugs.launchpad.net/ubuntu/+source/xorg/+bug/1922414
#


if type -t has_option >/dev/null; then
  return
fi


OPTIONS="$(
  if [ -r "$OPTIONFILE" ]; then
    cat "$OPTIONFILE"
  fi
  if [ -d /etc/X11/Xsession.options.d ]; then
    run-parts --list --regex '\.conf$' /etc/X11/Xsession.options.d | xargs -d '\n' cat
  fi
)"

has_option() {
  # Ensure that a later no-foo overrides an earlier foo
  if [ "$(echo "$OPTIONS" | grep -Eo "^(no-)?$1\>" | tail -n 1)" = "$1" ]; then
    return 0
  else
    return 1
  fi
}


2022-08-27

Cómo hago sobrecarga progresiva

 Hace 5 meses empecé a hacer pesas en el gimnasio que está a una cuadra de casa. Y estoy ganando fuerza. Para ganar fuerza en el gimnasio hay que hacer una cosa que se llama "sobrecarga progresiva". Eso quiere decir que a medida que vamos pudiendo, hay que ir haciendo los ejercicios cada vez más difíciles. En el caso de hacer pesas eso lo podés hacer subiendo el peso que usás en el ejercicio, subiendo la cantidad de repeticiones por serie y/o subiendo la cantidad de series. El problema es que subir el peso todo el tiempo no se puede porque las mancuernas suben de a 2.5kg, y los discos también (por lo que como hay que poner cantidades pares en la barra, el salto mínimo es de 5kg). Por lo tanto inventé este procedimiento, que está funcionando bárbaro.

Para cada ejercicio:

  1. Siempre hago 3 series.
  2. Y anoto cuanto peso y repeticiones hago en cada serie.
  3. En la última serie de cada ejercicio, trato de hacer todas las repeticiones que pueda (en vez de lo que tenía anotado). Si me excedo por 3 o más de lo que tenía anotado, la próxima hago una repetición más. Sino hago lo mismo que la vez anterior
  4. Si llego a 13 repeticiones (o sea, hago 15 repeticiones en la última serie cuando tenía anotadas 12), en vez de hacer 13 repeticiones la siguiente vez subo el peso lo menos que puedo (5kg en ejercicios con barra, 2.5kg en ejercicios con mancuerna) y hago 8 repeticiones (como tengo que levantar más peso, puedo hacer menos repeticiones).
  5. Cuando el salto es muy grande (por ejemplo, pasar en un ejercicio con mancuernas de 5kg a 7.5kg), en vez de llegar a las 13 repeticiones, trato de llegar a un número más grande (por ejemplo, 20 repeticiones).

 
No sé porqué no te cuenta nadie que ésta es la forma de ir subiendo de peso. Lo que vi en el gimnasio es que te suben los pesos independientemente de como progresás, y entonces o subís demasiado despacio o demasiado rápido y no podés hacer los ejercicios. Me pasó de decirle a un compañero de gimnasio que no tiene que levantar los pesos solo porque lo dice en su ficha. No hagas lo mismo. No te expongas al pedo. Seguí mi procedimiento (o algo parecido).

Y contame como te fue, o si tenés algún truco extra, en los comentarios.

2022-06-27

Montando directorios por ssh

 
Me gusta contectarme a mis VMs por ssh y es bastante cómodo. Pero a veces es un garrón copiar archivos desde/hacia mis VMs. Por eso prefiero montar el disco vía ssh. Saqué cómo hacerlo de acá.

Para hacer eso en ubuntu hay que instalar sshfs

$ sudo apt-get install sshfs

Hacer un directorio vacío para montar el filesystem nuevo.

$ mkdir /home/johndoe/sshfs-path/

Y montar el directorio vía ssh.

$ sshfs  remoteuser@111.222.333.444:/remote/path /home/johndoe/sshfs-path/

Por último, para desmontarlo hay que correr:

$ fusermount -u /home/johndoe/sshfs-path/

2022-04-28

Ignorando .gitignore

 A veces uno quiere ignorar archivos en git pero no quiere tocar .gitignore porque entonces aparece .gitignore como archivo modificado. Y eso es un garrón. Pensé que era inevitable, pero no. Si editan .git/info/exclude, poniendo reglas como las de .gitignore, va a ignorar siguiendo esas reglas en los comandos de git pero no van a ver .gitignore o .git/info/exclude como archivos modificados cuando corran git status (por ejemplo).

Fuente: https://stackoverflow.com/questions/653454/how-do-you-make-git-ignore-files-without-using-gitignore

2022-02-08

Buscando multiplicaciones y divisiones

Desde hace unos meses mi trabajo es hacer auditorías de smart contracts escritos en solidity. Como parte de este trabajo, tengo que buscar multiplicaciones y divisiones en código que no conozco, generalmente usando VSCode.

El tema es que las búsqueda de "*" y "/" dan bocha de falsos positivos porque estos caracteres se usan para marcar comentarios, aparte de las operaciones aritméticas. Por eso uso unas regex para buscarlos, que aunque no son perfectas, me sirven para acotar la cantidad de lugares que tengo que mirar. Quizás les sirvan a ustedes también, así que se las dejo acá abajo:

Multiplicación: [^\s].*[^/*]\*[^/*]

División: [^/*]/[^/*]

Probablemente también puedan serles útiles en otros lenguajes como Python, Java o C++.

2021-09-27

Setupeando hardhat para binance network

Estoy entrando a un laburo nuevo, y como primera tarea tengo que hacer unos POCs de contratos en solidity y testearlos en la red de test de Binance. 

Para hacer esto tengo que hacerlos con hardhat. Por lo tanto empecé a seguir las instrucciones que dan en Binance para setupear hardhat, pero no están del todo bien.

Los problemas que me llevé puestos son:

  • Hay que usar una versión LTS de nodejs. Para eso instalé nvm como dice acá e instalé el LTS usando nvm. La versión que trae ubuntu 20.04 haciendo apt install nodejs es muy vieja.
  • En el archivo hardhat.config.js que ponen ahí, hay que cambiar la versión de solidity a "0.8.4". Sino el contrato de ejemplo que genera cuando corrés npx hardhat no compila.
  • Hay que crear un archivo secrets.json donde poner los mnemonicos que usa metamask. El contenido del archivo es algo así: {"mnemonic": "a ante bajo cabe con contra de desde hacia hasta para por"}. 

Si el contenido de secrets.json no tiene el formato correcto, o el archivo no existe da un error bastante críptico (Expected a value of type HttpNetworkConfig)

Pero cuando está todo bien configurado pasa esto:

$ npx hardhat compile
Compiling 2 files with 0.8.4
Compilation finished successfully

Espero que les sirva,

Aureliano.

 


2021-08-25

Sistemas egoístas y bienes registrables



Seguramente esto sea un retroplagio, pero estuve notando que muchos sistemas suelen andar con incentivos opuestos, que hacen que llegue a un equilibrio.

Los mercados se basan en que haya compradores y vendedores, con intereses opuestos. El sistema judicial se basa en tener acusación y defensa. Yo creo que esa cualidad de que actores actuando de forma egoísta hacen que salga un resultado bueno es una propiedad deseable de los sistemas.

En particular, hay una aplicación de esto que creo que sería buenísimo hacer y no veo que la hagan. Uno de los problemas que hay con el cobro de impuestos es valuar correctamente los activos sobre los que se aplican. Por ejemplo, el precio de mercado de una propiedad. En Argentina (y creo que en el resto del mundo también) esta valuación se hace con una declaración, por lo que aún cuando se haga bien originalmente, esta valuación se vuelve incorrecta al toque (sobre todo cuando hay mucha inflación o una burbuja inmobiliaria).

Pero esto no tiene porqué ser así. Mi propuesta es usar un "sistema egoísta" para valuar bienes registrables, como por ejemplo terrenos o campos. En este sistema cada dueño declararía el precio de su propiedad, como hasta ahora, y se cobraría un impuesto como porcentaje del valor declarado, como hasta ahora. Lo nuevo es que puede venir cualquier otra persona o empresa y comprar dicha propiedad al doble del valor declarado. Si así lo hiciera, el dueño original se quedaría con el 150% del valor declarado y el 50% restante iría para el estado, en concepto de multa por no declarar correctamente el precio de la propiedad. Esto incentivaría a no sub-declarar el precio de las propiedades.

Algunas cosas que harían andar el sistema, evitando posibles abusos son:

  1. En caso de deber más del 20% del valor declarado de la propiedad en impuestos, la propiedad se subasta, se cobran los impuestos y lo que queda va al propietario.
  2. Para hacer una transferencia hay que llevar a 0 la deuda impositiva de la propiedad.
  3. Para cambiar la valuación de la propiedad hay que llevar a 0 la deuda impositiva de la propiedad.
  4. Para propiedades, no se puede declarar un valor que sea 3 veces superior al valor por metro cuadrado de propiedades similares. Esto es para evitar que declaren un valor muy grande que haga que el 20% del valor declarado sea más que el precio de mercado de la propiedad, haciendo que sea más barato no pagar los impuestos y dejar que la subasten cuando la deuda llegue al límite de subasta.
  5. Hay que poner algún mecanismo sensato de indexación del precio declarado, para evitar que la inflación lo deje muy bajo y haya gente que se aproveche de eso. Quizás ajustar por CER o RIPTE o indice minorista del INDEC por defecto. Este ajuste no requiere llevar la deuda impositiva a 0, y la deuda debería ajustarse por el mismo índice (y quizás aparte algún punitorio para desincentivar tomar la deuda).

 
Creo que si se usara esto para cobrar impuestos a los latifundios de la pampa húmeda, podrían darse las condiciones para que no haya más dólares paralelos ni retenciones a las exportaciones. Y si funciona bien, aplicarla después al resto de las propiedades también.

Espero que alguien tome esta idea y la lleve a cabo.


2021-07-23

Desarrollar con rust en una VM

 En estos días empecé a jugar un poco con rust. Para esto, armé un entorno de desarrollo razonable para mi, en una VM. A mi me gusta armar entornos en VMs para desarrollar así no contamino mi compu con todas las cosas que voy instalando para probar cosas. En particular, prefiero armar VMs de lubuntu (ubuntu con lxde) y laburar conectandome via ssh como si fuera otra compu.

Para esto, armé la VM y le puse 2 placas de red virtuales (una NAT y otra host-only), le instalé lubuntu, le apliqué los últimos paquetes (apt update y apt upgrade) openssh-server (apt install openssh-server), git (apt install git), vscode (snap install --classic code), curl (apt install curl) y rust via rustup (curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh) que incluye cargo.

Para laburar más cómodo le informé mi clave de ssh a la VM usando ssh-copy-id. Después de eso, puedo sshearme a la vm (ssh -X -A aure@192.168.56.101) y operar sin poner passwords y abrir ventanas remotas para usar el vscode (y firefox) de la VM en el escritorio del host.

Para usar firefox hay que correrlo como firefox -no-remote. Para que anden los comandos de cargo y rustup que abren el browser agregué export BROWSER="$HOME/bin/firefox-remote.sh" en el final de mi .profile de la VM. y en $HOME/bin/firefox-remote.sh puse

#!/usr/bin/env bash

firefox -no-remote "$@"

y lo puse como ejecutable con chmod.

En vscode instalé 3 plugins:

  • GitLens para tener mejor soporte para git
  • Rust para tener soporte de la sintaxis de rust
  • CodeLLDB para poder debuggear código de rust dentro de vscode

Con esto creo que estoy listo para empezar a programar dentro de mi VM.

¿Creen que me faltó algo?

2021-04-14

Evitando freezes de la memoria de estado sólido

Tengo una notebook nueva con una ssd kingston de 1 tera, modelo SA2000M81000G según smartctl. Cuando uso la notebook, en forma bastante aleatoria, se pega unos cuelgues de novela. Después de estar como un mes tratando de entender que &&*$#$#&$@#* pasa, creo que encontré la respuesta :D.

Parece que algunas memorias kinsgton tienen un bug que se manifiesta cuando cambian de estado para ahorrar energía. El manejo de energía está en el kernel. 

La forma de evitarlo es pasarle un parámetro a grub como explican acá.

En mi ubuntu, edité el archivo /etc/default/grub. Cambié la línea GRUB_CMDLINE_LINUX="" para que diga GRUB_CMDLINE_LINUX="nvme_core.default_ps_max_latency_us=0". Después de eso corrí sudo update-grub y reinicié la compu. 

Después de eso, parece que anda todo bien 🤞.


PD: Están trackeando este bug acá

2021-03-05

Memtest Ubuntu booteando desde EFI

Lamentablemente, la opción para correr memtest cuando booteamos no está disponible cuando booteamos de una compu que usa EFI en vez de BIOS.

Por suerte, hay workarround. Casi todos los pasos están documentados acá. La única diferencia para la compu en la que tuve que hacer esto es que, como bootea de memoria de estado sólido, en vez de bootear de /dev/sda4 (o parecido) bootea de /dev/nvme0n1p1, por lo que las instrucciones sobre cómo armar el script para que grub tenga la entrada son un poquitín distintas.

En mi caso el archivo /etc/grub.d/40_memtest es así (en rojo lo que cambié)

#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
 
menuentry 'memtest86' {
    insmod part_gpt
    insmod fat
    set root='hd1,gpt1'
    chainloader /EFI/memtest86/BOOTX64.efi
}

No tengo muy claro porqué funciona (fue un SWAG).

Espero que les sirva,

Aureliano.

2021-03-03

pingmon en python3

Hace un tiempo hice un scriptcito en python para monitorear la conexión de red usando ping. Hoy quise usarlo de nuevo y descubrí que no anda en python3, así que lo adapté. Solo necesitaba 2 pequeños cambios:

  • print es python3 es una función, así que tuve que agregar unos paréntesis.
  • sys.stdout.readline() en python 3 devuelve un montón de bytes (en vez de un string) así que agregué .encode() para transformarlo en string

Dejo acá abajo la versión nueva:

#!/usr/bin/env python3

import subprocess
import sys
import re

SEQ_NUMBER_RE = re.compile(".*icmp_seq=(\d+) ttl.*")

def report(probes, count):
  if len(probes) < count:
    return "N/A"
  return str ( count - sum(probes[-count:]) )

def monitor(ip):
  probes = []
  ping = subprocess.Popen(["ping", ip], stdout=subprocess.PIPE)
  stdout = ping.stdout

  stdout.readline() # Ignore first line
  line_count = 0
  last_seq_number = 0
  while True:
    line_count +=1
    seq_number = int( SEQ_NUMBER_RE.match(stdout.readline().decode()).group(1))
    probes.extend([0] * (seq_number - last_seq_number - 1))
    probes.append(1)
    print( "(%s) 10:%s 100:%s 1000:%s" % (
      line_count, report(probes, 10), report(probes, 100), report(probes, 1000)
    ) )

    probes = probes[-1000:] # Keep memory usage bounded
    last_seq_number = seq_number

def main(argv):
  monitor(argv[1])

if __name__ == '__main__':
  main(sys.argv)

 

Happy hacking,
Aureliano