Tive de trabalhar nessa semana com um caso que me exigiu usar o pycurl no Python. O problema foi que escrevi um script que rodava baixando artefatos de build no Jenkins usando o módulo requests, e o mesmo não funcionava mais no Gitlab.
Depois de gastar um pouco de tempo no request
, e usando o curl
do exemplo do site do Gitlab, eu acabei desistindo e indo pra usar o pycurl
no script. De cara descobri que não tinha pycurl
instalado. E no MacOS não foi tão simples como poderia ter sido. A receita de bolo pra instalar o pycurl foi a seguinte sequência:
helio@MacOS> arch -arm64 brew install openssl curl helio@MacOS> export PATH=/opt/homebrew/opt/curl/bin:$PATH helio@MacOS> export LDFLAGS="-L/opt/homebrew/opt/curl/lib":$LDFLAGS helio@MacOS> export CPPFLAGS="-I/opt/homebrew/opt/curl/include":$CPPFLAGS helio@MacOS> arch -arm64 pip install --no-cache-dir --compile --ignore-installed --install-option="--with-openssl" --install-option="--openssl-dir=/opt/homebrew/Cellar/openssl@3/3.0.7" pycurl
Quando algo funciona em curl
é fácil escrever o código em python. Basta rodar com o parâmetro --libcurl foo.c
que ele joga o código em funcionou dentro do arquivo.c no formato pra linguagem C, mas é bem próximo do uso em python.
hnd = curl_easy_init(); curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, 102400L); curl_easy_setopt(hnd, CURLOPT_URL, "https://gitlab.[redacted]/api/v4/projects/[redacted]/jobs/[redacted]/artifacts"); curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L); curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, slist1); curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/7.86.0"); curl_easy_setopt(hnd, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_2TLS); curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
Em python:
url = "https://gitlab.[redacted]/api/v4/projects/[redacted]/jobs/[redacted]/artifacts" buffer = BytesIO() c = pycurl.Curl() c.setopt(c.URL, url) c.setopt(c.BUFFERSIZE, 102400) c.setopt(c.NOPROGRESS, 1) if GITLAB_PRIVATE_TOKEN: c.setopt(c.HTTPHEADER, [ "PRIVATE-TOKEN:" + GITLAB_PRIVATE_TOKEN ]) else: c.setopt(c.HTTPHEADER, [ USERNAME + ":" + PASSWORD]) c.setopt(c.USERAGENT, "curl/7.84.0") c.setopt(c.FOLLOWLOCATION, 1) c.setopt(c.HTTP_VERSION, c.CURL_HTTP_VERSION_2TLS) c.setopt(c.TCP_KEEPALIVE, 1) c.setopt(c.WRITEDATA, buffer) c.perform() c.close()
E assim o código saiu funcionando.
Por algum motivo bizarro, a Apple inclui essa tecla esquisita no teclado de seus notebooks. Tenho no MacBook Pro que uso, mas já vi que é a mesma coisa em outro modelos como o MacBook Air. Como eu uso boa parte do tempo em casa, onde tenho um teclado mecânico, quase nunca percebo o problema dessa tecla alienígena instalada. Mas basta eu trabalhar só no laptop em hackathons e outros eventos pra começarem os problemas. Principalmente quando vou mexer no shell e passar o "~" pra usar como abreviação do HOME.
Hoje, um dos raros dias que faço isso, resolvi mexer no laptop na sala pra assistir à copa do mundo e acertar algumas coisas no raspberrypi. Além de escrever pro blog aqui. Eis que o raio da tecla "~" faz falta. Mas dessa vez resolvi buscar alguma solução na Internet. E achei!
https://apple.stackexchange.com/questions/281405/easy-way-to-remap-non-modifier-keys-on-mac
Basicamente é rodar o seguinte comando:
MacOS@helio> hidutil property --set '{"UserKeyMapping": [{"HIDKeyboardModifierMappingSrc":0x700000035, "HIDKeyboardModifierMappingDst":0x700000064}, {"HIDKeyboardModifierMappingSrc":0x700000064, "HIDKeyboardModifierMappingDst":0x700000035}] }'
Isso já configura a tecla corretamente. E pra iniciar durante o boot, criar o arquivo ~/Library/LaunchAgents/com.user.loginscript.plist
com o seguinte conteúdo:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.user.loginscript</string> <key>ProgramArguments</key> <array> <string>/usr/bin/hidutil</string> <string>property</string> <string>--set</string> <string>{"UserKeyMapping":[{"HIDKeyboardModifierMappingSrc":0x700000035, "HIDKeyboardModifierMappingDst":0x700000064}, {"HIDKeyboardModifierMappingSrc":0x700000064, "HIDKeyboardModifierMappingDst":0x700000035}]}</string> </array> <key>RunAtLoad</key> <true/> </dict> </plist>
E chamar na inicialização assim:
MacOS@helio> launchctl load ~/Library/LaunchAgents/com.user.loginscript.plist
E pronto! Tecla funcional. Agradeço de coração quem deu essa resposta maravilhosa no stack exchange.
UPDATE: Sun Nov 27 19:27:29 CET 2022
Quando fui usar o laptop conectado no teclado externo, tive a triste verificação de que os comandos acima troca uma tecla pela outra, o que é altamente indesejado. O que eu quero é mesmo sumir com a tecla do "±" que não uso.
Pra isso eu precisei modificar o comando anterior para:
MacOS@helio> hidutil property --set '{"UserKeyMapping": [{"HIDKeyboardModifierMappingSrc":0x700000064, "HIDKeyboardModifierMappingDst":0x700000035}] }'
E o mesmo pra ~/Library/LaunchAgents/com.user.loginscript.plist
:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.user.loginscript</string> <key>ProgramArguments</key> <array> <string>/usr/bin/hidutil</string> <string>property</string> <string>--set</string> <string>{"UserKeyMapping":[{"HIDKeyboardModifierMappingSrc":0x700000064, "HIDKeyboardModifierMappingDst":0x700000035}]}</string> </array> <key>RunAtLoad</key> <true/> </dict> </plist>
E agora tenho a tecla "~" em ambos os teclados. Precisei dar um "reload" no launchctl pro caso do teclado:
MacOS@helio> launchctl unload ~/Library/LaunchAgents/com.user.loginscript.plist MacOS@helio> launchctl load ~/Library/LaunchAgents/com.user.loginscript.plist
Esse problema já vinha arrastando-se por algum tempo. Desde que peguei o MacBook. Quando eu trabalhava com um display externo, o Firefox ficava com a fonte normal. Mas bastava eu usar somente o laptop pra ele ficar ridiculamente pequeno. Como pode ser visto na image, o texto é legível, mas a barra do Firefox é impossível. E em alguns sites específicos eu precisava ficar aumentando o zoom pra conseguir ler o texto.
No Macos eu já tinha configurado pra usar uma resolução não tão alta pra justamente não ficar com tudo ridiculamente pequeno na tela (eu particularmente odeio isso).
Mas o Firefox sempre teimava em não seguir a configuração. E o difícil era... buscar um solução já que eu não sabia qual o problema exatamente. Tentei "firefox small fonts", "firefox small resolution" e por aí seguiu minha busca. Sem infrutífera. Até que hoje eu resolvi buscar por "hidpi" e... bingo!
Basta entrar na configuração do Firefox com "about:config" e alterar o parâmetro "layout.
e como ficou depois, só mudando de 1 pra 1.5.
agora sim consigo usar apenas o laptop pra trabalhar.
Descobri através daqueles links obscuros que aparecem na segunda página de buscas do duckduck.go uma referência a um servidor Jenkins do KDE.
E pra minha surpresa, ou melhor, para meu deleite tem okular, dolphin e outras coisas práticas e excelentes pra rodar no Macos.
Depois de baixar e montar o arquivo dmg, usando como exemplo o Dolphin, você precisa copiar o arquivo pra suas aplicações e dar as permissões pra ele rodar:
$ xattr -d com.apple.quarantine /Applications/dolphin.app $ codesign --sign - --force --deep /Applications/dolphin.app
E basta iniciar o programa:
$ open -a /Applications/dolphin.app
Ookular funcionou sem problemas.
O Dolphin está com algum problema de tema que não aparecem os nomes de diretórios. Também senti falta do "single click" pra abrir os diretórios, mas já é infinitamente melhor que o "finder" do Mac.
Talvez o konsole algum dia também apareça nessa lista.
Enquanto isso não acontece, esse aqui é o link do Jenkins:
Eu já passei do tempo de comentar sobre esse assunto aqui, então hoje vou aproveitar que perguntaram sobre esse tema e escrever o que tenho feito.
Primeiro eu preciso explicar mais sobre meu dia à dia no trabalho. O que faço é compilar código em Go, criar e configurar helm charts e gerar containers. Pra isso temos um containers base de desenvolvimento que criamos baseado em Ubuntu 20.04 (e que precisamos atualizar pro 22.04 algum dia). Com o brew eu instalei todas as ferramentas que preciso e uso como o próprio compilador Go, fish shell, Python, git, kubectl, helm, etc. A única coisa foi que precisei alterar o meu PATH pra ler do brew ao invés do PATH normal. Então eu tenho algo como:
if [ "$OperatingSystem" = "Darwin" ]
set -gx PATH /opt/homebrew/bin /opt/homebrew/sbin $PATH $HOME/bin $HOME/.local/bin $HOME/go/bin
end
nas minhas configurações do fish.
Um dos motivos de forçar isso é que o bash que vem no Apple é uma versão muito velha. Então é melhor rodar a versão mais recente através do brew. E descobri que alguns scripts dava problemas com... getopts. Sim, o programa que usamos pra ler opções de scripts. Até isso precisei usar o que vem do brew. Aparentemente o Apple tem um getopt que é BSD e não funciona com as configurações da GNU. Mas seu script não sabe disso. Então tive de forçar a precedência dos binários do brew.
$ which -a bash
/opt/homebrew/bin/bash
/opt/homebrew/bin/bash
/bin/bash
$ /opt/homebrew/bin/bash --version
GNU bash, version 5.2.2(1)-release (aarch64-apple-darwin21.6.0)
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin21)
Copyright (C) 2007 Free Software Foundation, Inc.
$ which -a getopt
/opt/homebrew/bin/getopt
/opt/homebrew/bin/getopt
/usr/bin/getopt
$ /opt/homebrew/bin/getopt --version
getopt from util-linux 2.38.1
$ /usr/bin/getopt --version
--
Além disso precisei mudar quase todos os shebangs dos shell scripts pra #! /usr/bin/env bash pra evitar rodar com o bash do sistema.
E como bom usuário de Linux eu não uso nada que tenha de pagar. Nem na loja da Apple eu registrei. Aliás criei um login e entrei pra baixar o skitch pra usar de screenshot saver como usava o flameshot, já que o que vem com o sistema é miserável o uso. Mas o restante eu instalo tudo via brew. E assim instalei o UTM, que na loja da Apple é pago mas via brew é só instalar e usar.
Por baixo do UTM roda tudo em qemu. Mas ele tem uma interface bacana de gerenciamento.
Eu instalei um Ubuntu 20.04 x86_64, chamado de amd64 (e guarde esse nome), e armv8, chamado de aarch64 ou arm64. Eu uso mais a versão pra ARM porque essa roda via VM usando a CPU nativa e é bem rápida, enquanto o x86_64 é via emulação e é bastante lento, além de ter problemas na emulação de tempos em tempos.
Nesse Linux eu instalei um pacote recente do qemu estático pra poder rodar o Docker multiplataforma.
# Latest qemu for docker/bob
RUN curl -OL http://ports.ubuntu.com/ubuntu-ports/pool/universe/q/qemu/qemu-user-static_6.2+dfsg-2ubuntu6.4_arm64.deb \
&& dpkg -i qemu-user-static_6.2+dfsg-2ubuntu6.4_arm64.deb \
&& rm qemu-user-static_6.2+dfsg-2ubuntu6.4_arm64.deb
Como são binários estáticos, você pode pegar qualquer pacote, inclusive do Debian mesmo, e instalar. A versão que vem com o Ubuntu dá um crash no kernel do Apple e reboot o laptop, então pegue essa última versão e tenha certeza de ter aplicado os últimos patches de seguranças do Macos.
Agora começa o balaio de gato de plataformas. O pacote, como pode ser visto acima, é chamado "arm64". Mas se eu entro no meu terminal no Apple, o que tenho é isso:
$ uname -m
x86_64
$ uname -a
Darwin EMB-QG9ND6H2 21.6.0 Darwin Kernel Version 21.6.0: Mon Aug 22 20:19:52 PDT 2022; root:xnu-8020.140.49~2/RELEASE_ARM64_T6000 x86_64
e dentro da VM rodando Linux/arm64:
$ uname -m
aarch64
$ uname -a
Linux ubuntu-2004 5.4.0-128-generic #144-Ubuntu SMP Tue Sep 20 11:03:09 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux
então já começa o balaio de gato aí. O Apple acha que ele é um x86_64, o que não é verdade. Linux diz que é aarch64, mas os pacotes referem-se à arm64.
Pra fazer isso você entra na configuração do Docker e adiciona a seguinte linha:
"experimental": "enabled"
isso habilite o build em múltiplas plataformas. Ou chamar o container de outras plataformas.
Então pra fazer um build x86_64 você usa algo como:
$ docker build --platform=linux/amd64 .
e um exemplo baixando um container baseado em alpine e usando:
$ docker pull --platform=linux/amd64 quay.io/aptible/alpine
Using default tag: latest
latest: Pulling from aptible/alpine
207e252fc310: Pull complete
8a9527e58fed: Pull complete
cdb7f38bc74b: Pull complete
3eb2d0c301f8: Pull complete
Digest: sha256:9790231800450f0e5fb93c03aecd22de0d5d43ae9898aa713350bdbeb9bd1e70
Status: Downloaded newer image for quay.io/aptible/alpine:latest
quay.io/aptible/alpine:latest
$ docker run --rm --platform=linux/amd64 quay.io/aptible/alpine uname -a
Linux 249590268d5c 5.4.0-128-generic #144-Ubuntu SMP Tue Sep 20 11:03:09 UTC 2022 x86_64 Linux
E pronto. Lembram que escrevi acima sobre a bagunça de nomenclaturas e que o amd64 era usado em algum momento? Pois olha ele aí.
Mas nem tudo são flores. Descobri alguns problemas quando parte do nosso build usa ferramentas feitas em... Java! Ou o container trava (e por sua vez a instância do qemu rodando) ou gera um core dump.
O erro é o mesmo descrito aqui:
https://github.com/adoptium/temurin-build/issues/893
mas eu acho que o bug não do openjdk ou do jdk, porque testei também com o jdk da própria Oracle, mas da emulação do qemu.
Isso foi no começo da minha aventura. Depois de um tempo eu vi um vídeo sobre o Rancher Desktop e resolvi testar. Primeiro que tive de configurar pra usar Docker nativo.
Pra rodar o rancher corretamente eu precisei solicitar acesso root à máquina via sudo, que não é dado por padrão e é preciso solicitar. Mas após isso, roda a partir do próprio macos sem precisar da VM.
$ docker pull --platform=linux/amd64 quay.io/aptible/alpine
Using default tag: latest
latest: Pulling from aptible/alpine
207e252fc310: Pull complete
8a9527e58fed: Pull complete
cdb7f38bc74b: Pull complete
3eb2d0c301f8: Pull complete
Digest: sha256:9790231800450f0e5fb93c03aecd22de0d5d43ae9898aa713350bdbeb9bd1e70
Status: Downloaded newer image for quay.io/aptible/alpine:latest
quay.io/aptible/alpine:latest
$ docker run --rm --platform=linux/amd64 quay.io/aptible/alpine uname -a
Linux 1a7f8e55ce09 5.15.57-0-virt #1-Alpine SMP Fri, 29 Jul 2022 07:15:20 +0000 x86_64 Linux
mas sofre do mesmo problema que o UTM em relação ao Java. No momento eu tenho usado mais a VM no UTM por ser um pouco mais rápida que o container no Rancher Desktop/Docker. E o que faço é trabalhar no Macos, geralmente usando VSCode da Microsoft mesmo, e mandando um git push pro meu repo na VM. E lá rodando testes.
Não é um workflow muito prático, mas pra mim tem funcionado bem.