Sin categoría

How to Fix the «Configuring Remote PC…» Issue on Mac with Microsoft Remote Desktop App»

I recently ran into a peculiar issue with my Apple Mac M3 Pro while trying to connect to a newly set up laptop via the Microsoft Remote Desktop 10.9.5 (2179). The laptop was freshly installed with an Ubuntu 22.04. Typically, I can connect to various computers both locally and remotely without a hitch. However, this time, I was stuck at the «Configuring remote PC…» screen indefinitely, and the connection just wouldn’t go through.

Initially, I thought the problem might lie within the Linux configurations of the new laptop. However, after some troubleshooting ensuring the ‘gnome-remote-desktop’ (not «xrdp») service was properly set up, I stumbled upon the real culprit: Clipboard sharing. It turns out everything else worked fine—printer sharing, smart card access, and even audio and video functionalities were not affected. But the moment I tried to use the keyboard, things went south.

The fix? Simply disabling the Clipboard sharing feature in the Microsoft Remote Desktop app. This workaround immediately resolved the connection issue, allowing me to finally access the laptops.

For now, I’ve decided to keep the Clipboard sharing disabled. While this isn’t ideal, it’s a small price to pay for being able to connect to these Linux systems. I’m planning to dive deeper into this issue, but that’s a task for another day.

Interestingly, when I tried connecting to these Linux laptops from a Windows 11 PC using the standard Remote Desktop Connection client, everything worked perfectly. This experience led me to think that the issue might not be with the Linux systems themselves but rather with how the Microsoft Remote Desktop client on Mac handles the connection, particularly in authenticating and selecting the session (e.g., «Ubuntu» or «Ubuntu on Xorg»).

So, if you’re facing a similar «Configuring remote PC…» freeze on your Mac when trying to connect to a Linux system, try turning off Clipboard sharing in the Microsoft Remote Desktop app. It’s a quick fix that might just do the trick until a more permanent solution is found.

Enjoy!

Sin categoría

npm install will randomly hang forever on a Linux Virtual Machine running on an Apple M3

First of all, I’d like to mention that this is in relation to this issue.

Having said that, the solutions suggested by many, such as disabling IPv6 in the Mac OS Wi-Fi Network settings, will not work. Similarly, changing the npm repository, or disabling https for npm, also prove ineffective.

Given that there’s not much to glean from the npm logs, even with extra verbosity or debug information enabled, I suspect the issue is related to the npm version itself.

In my development environment, which includes a brand new MacBook Pro M3 running Mac OS Sonoma 14.2.1, Parallels Desktop 19.2.1, and a fresh Debian 12 ARM Virtual Machine, the default versions of node and npm installed with the command:

apt install nodejs npm -y
node: v19
npm: v9

These versions seem to be the culprits behind the npm command freezing.

I managed to resolve this by installing the latest LTS version of Node (20) and its corresponding npm version using the nvm tool.

The steps to resolve the issue are straightforward: install nvm and then use nvm to install node 20. Here’s how:

curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
nvm install 20.10
nvm alias default 20.10

The last command is optional, but I prefer using it.

Now, when running any npm install command, such as npm install express (which was the one causing my issue), it proceeds without issues.

Enjoy!

LARAVEL, Programación Web

Custom Hasher for Laravel 10 (PHP Crypt wrapper)

En el proyecto en el que estamos trabajando surge la necesidad de lidiar con una base de datos de usuarios con varios cientos de miles de registros. Todos los usuarios disponen de password ‘hasheado’ pero, lamentablemente, usando el algoritmo PHP crypt, no soportado ‘out-of-the-box’ por Laravel 10 (ni tampoco en versiones anteriores recientes).

No podemos cambiar el algoritmo por alguno de los soportados por Laravel: «bcrypt», «argon», «argon2id»

La documentación oficial de Laravel al respecto de la capacidad de crear drivers válidos para la clase Hash es muy escueta. Así que pongámonos manos a la obra.

Crea la clase PHPCryptHasher y ubícala donde quieras. Una forma sencilla sería almacenarla en la carpeta Services de tu proyecto. En mi caso, prefiero crear un package externo para poderlo reusar con composer en otros proyectos.

PHPCryptHasher.php

<?php

namespace App\Services;
use Illuminate\Contracts\Hashing\Hasher;

class PHPCryptHasher implements Hasher
{

    public function info($hashedValue)
    {
        return ['hash' => $hashedValue];
    }

    public function make($value, array $options = [])
    {
        return isset($options['salt']) 
            ? crypt($value, $options['salt'])
            : password_hash($value, PASSWORD_DEFAULT);
    }

    public function check($value, $hashedValue, array $options = [])
    {
        $hash = $this->make($value, ['salt' => $hashedValue]);
        return hash_equals($hash, $hashedValue);
    }

    public function needsRehash($hashedValue, array $options = [])
    {
        return false;
    }
}

Crear o editar el proveedor de servicio

Edita el archivo AppServiceProvider.php (o crea uno ad-hoc para este propósito). Este sería el contenido:

<?php

namespace App\Providers;

use App\Services\PHPCryptHasher;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        app('hash')->extend('phpcrypt', function ($app) {
            return new PHPCryptHasher();
        });
    }
}

Editar la configuración del proyecto

Edita el archivo de configuración de Laravel ‘config/hashing.php’ y añade la referencia a ¨phpcrypt¨, que es la forma en que hemos definido nuestra extensión al hacer el extend en el paso anterior.

<?php

return [

    'driver' => 'phpcrypt',

    ... deja el resto del código igual
];

Listo!

Ya tenemos lista nuestra extensión para PHP crypt. A partir de este momento, al realizar una llamada al facade Hash se utilizará la classe PHPCryptHasher tal y como se muestra acontinuación usando una sesión con ¨artisan tinker¨:

$ artisan tinker

Psy Shell v0.11.14 (PHP 8.1.18 — cli) by Justin Hileman
> Hash::make('11')
= "$2y$10$7T/q.oxp9.N4.OnX4A9mDOJL0glMPin7SZC1vq9nhTMOKL8kQb.qO"

> Hash::driver()
= App\Services\PHPCryptHasher {#4278}


Mac OSX y iOS, Programación Web

Installing PHP8.0 for Apache in Mac OS Monterrey is tricky but feasible

Are you trying to install the PHP module for Apache in your Mac OS and you are facing an error?

"No code signing authority for module at /usr/local/opt/php@8.0/lib/httpd/modules/libphp.so specified in LoadModule directive.
httpd: Syntax error on line NNN of /private/etc/apache2/httpd.conf: Code signing absent - not loading module at: /usr/local/opt/php@8.0/lib/httpd/modules/libphp.so"

Mac OS Monterey and newer versions of the OS, requires all apps to be verified (hence signed) in order to be executed by the OS.

Since you are installing PHP8.0 using HomeBrew (or from any similar «unsafe» source like MacPorts), the binaries installed in your system are not directly trusted by the OS. Because of this, the Apache server will fail to start.

The way to go is to sign the binaries by ourselves and let the OS think that they are «safe».

So,

How to install PHP8.0 and configure Apache on Mac OS Monterrey or later?

You can follow up this guide for any other PHP version, but since I need to use one to proceed, I will use the 8.0 version.

So, first of all, let us install PHP using HomeBrew. If you don’t have it already installed, follow up the official guide: https://brew.sh

Let’s get to work:

$ brew install php@8.0

...


$ echo 'export PATH="/usr/local/opt/php@8.0/bin:$PATH"' >> ~/.zshrc
$ echo 'export PATH="/usr/local/opt/php@8.0/sbin:$PATH"' >> ~/.zshrc
$ export LDFLAGS="-L/usr/local/opt/php@8.0/lib" >> ~/.zshrc
$ export CPPFLAGS="-I/usr/local/opt/php@8.0/include" >> ~/.zshrc
$ source ~/.zshrc

I assume that you are using Zsh; if you don’t replace .zshrc by .bashrc

PHP is ready for being used as any other program in our OS:

$ php -v

PHP 8.0.25 (cli) (built: Oct 31 2022 08:58:29) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.25, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.25, Copyright (c), by Zend Technologies

However, as mentioned above, it’s not enough when you need the PHP interpreter to be used by your web server (Apache for this guide). And this is generally what we want to do, aren’t we?

Before going further, let me just show you what Apache reports if we try to directly enable the PHP module without signing it.

Enable the PHP8.0 module on Apache

Edit the /etc/apache2/httpd.conf configuration file using your favourite editor (nano, vi, vim, …) as a superuser (sudoers).

$ sudo nano /etc/apache2/httpd.conf

Lookup for the LoadModule sentences (they are many) and paste this line after the last one you have found:

LoadModule php_module /usr/local/opt/php@8.0/lib/httpd/modules/libphp.so

Save the changes.

NOTE: There is something intentionally missing on this line but I will explain about it later. For now, just keep it as is. Save the changes to the configuration file and trust me 😉

To check if Apache and the OS digests the new module reference, simply run either:


$ apachectl configtest

or

$ apachectl -t

As mentioned above, due to the OS security restrictions, attempting to load the «unsigned» PHP module will result in:

[Sat Nov 19 10:32:37.373665 2022] [so:error] [pid 93724] AH06665: No code signing authority for module at /usr/local/opt/php@8.0/lib/httpd/modules/libphp.so specified in LoadModule directive.
httpd: Syntax error on line 190 of /private/etc/apache2/httpd.conf: Code signing absent - not loading module at: /usr/local/opt/php@8.0/lib/httpd/modules/libphp.so

Cool, isn’t?

Therefore it is mandatory to sign the PHP module for being loaded by Apache (or NGINX, or any other web browser).

Do not panic! It is not a big deal after all.

What do we need to sign a binary on Mac OS? Formally named «Code Signing»

For singing any application we need 3 things:

1- A tool (software) for signing. This means a software that will stamp a signature over a file.

2- A CA (Certificate Authority) that will act as a «validator» of a Code Signing Certificate.

3- A Code Signing Certificate

You can read a little bit about it here

On Mac OS, the tool used for code signing is provided as part of Apple xcode. So it is the first thing we need to install if it is not already in our Mac OS.

Steps to self signing software in Mac OS

As aforementioned, first of all install codesign, if it is not yet there, running the following command:

$ xcode-select --install

Once installed you will be able to check the CA (Certification Authority) used for the PHP8.0 module:

$ codesign -dv --verbose=4 "/usr/local/opt/php@8.0/lib/httpd/modules/libphp.so"

As expected, it will result in:

/usr/local/opt/php@8.0/lib/httpd/modules/libphp.so: code object is not signed at all

So, since we have the tool for signing, let us move one step further creating a CA.

Create a fake Certificate Authority (CA) on Mac OS

Open the Keychain Access application. You can easily do it by pressing CMD+Space (to open Spotlight), typing «Keychain Access» and selecting it from the list.

Navigate to «Keychain Access» top menu and select Certificate Assistant / Create a Certificate Authority…

Screen Shot 2022-11-19 at 10.51.56.png

Type the name you want for your fake CA (but remember it ;-)), your email (may be fake if you want), select the «Code Signing» user certificate type and check the «Let me override defaults»:

Screen Shot 2022-11-19 at 10.55.54.png

Click continue and keep all the defaults at the next screen. 

Screen Shot 2022-11-19 at 12.02.14.png

You will -probably- get an alert:

Screen Shot 2022-11-19 at 10.58.25.png

Just ignore the alert and continue. 

Set the data you want but remember the name you type. Everything may be fake or real, do not worry about providing valid information.

Screen Shot 2022-11-19 at 10.59.21.png

Click on continue and keep the defaults 2048 bits for the Key Size and RSA for the Algorithm twice («Key Pair Information For This CA» and «Specify Key Pair Information For Users of This CA» views).

In the view «Key Usage Extension For This CA» Keep also the defaults with the checks at «Key Usage Extension», «Signature» and «Certificate Signing» on the next view and click continue.

Again, in the view «Key Usage Extension for Users of this CA» keep also the defaults with the checks at «Key Usage Extension», «This extension is critical» and «Signature» on the next view and click continue.

In the next view ensure you select the «Include Extended Key Usage Extension» and «Code Signing»:

Screen Shot 2022-11-19 at 11.03.29.png

At the next views keep the defaults and continue:

Screen Shot 2022-11-19 at 11.04.33.png
Screen Shot 2022-11-19 at 11.04.59.png
Screen Shot 2022-11-19 at 11.05.31.png
Screen Shot 2022-11-19 at 11.05.46.png
Screen Shot 2022-11-19 at 11.06.07.png

At the last step keep the defaults as well and select «Create»:

Screen Shot 2022-11-19 at 11.06.31.png

You can just ignore the confirmation view shown after.

Search now the certificate typing the name you provided (Fake CA in my case) and right click to ‘Get Info’:

Screen Shot 2022-11-19 at 11.08.45.png

Here it is an excerpt of mine where I already click on the ‘Trust’ panel:

Screen Shot 2022-11-19 at 11.11.19.png

Set the ‘When using this certificate to «Always trust» and all the other options will automatically be populated to the same value.

Screen Shot 2022-11-19 at 11.12.50.png

Close the window and, when prompted, confirm your username and password to permanently store it to the KeyChain.

Refresh the certificates list and you will see now the certificate displayed as valid:

Create a Code Signing certificate based on our fake CA

For what we need that? A Code Signing certificate it is a certificate issued by a known CA (our fake one it is now «known» ;-)) used to sign a binary file. When the OS attempts to execute the binary, it detects the binary it is signed and it asks to the issuer CA about its authenticity.

Access the KeyChain main menu and select Open.

Screen Shot 2022-11-19 at 11.24.27.png

In the next view select «Create a certificate for yourself» and click «continue».

Type now the name you want to set for the certificate issuer, select «Leaf» as the «Identity Type» and «Code Signing» for the Certificate Type.

Please take note about the name you used because you will need it later on.

Select your recently created CA from the list:

Screen Shot 2022-11-19 at 11.27.10.png

Click on Create to finish the process.

Screen Shot 2022-11-19 at 11.27.32.png

Congratulations! Your Code Signing certificate has been issued and it is trusted by our Mac OS. Click in «Done» to finish.

How easy is it to fake a CA and lie to our Mac OS right? 😉

Codesigning the PHP8.0 binaries in our Mac OS using the fake Code Signing certificate

Once we have created both the Certificate Authority and the code signing certificate, we will be using them with codesign to sign the php module. It is the way to make it «verified application» for the Mac OS eyes. 

Open a Terminal / Command Line tool to run the codesign command using the issued certificate.

Run the following command changing «Alex Conesa» by the name you set when you created your Code Signing certificate:

$ codesign --sign "Alex Conesa" --force --keychain ~/Library/Keychains/login.keychain-db

/usr/local/opt/php@8.0/lib/httpd/modules/libphp.soShould result in:/usr/local/opt/php@8.0/lib/httpd/modules/libphp.so: signed Mach-O thin (x86_64) [libphp]

Now it is time to set the correct CS reference in the Apache configuration file.

Edit the /etc/apache2/httpd.conf file and define the CS we just created at the end of the line:

LoadModule php_module /usr/local/opt/php@8.0/lib/httpd/modules/libphp.so "Alex Conesa"

Verify the Apache configuration file:

$ apachectl configtest


[Sun Nov 20 11:41:07.772994 2022] [so:notice] [pid 97504] AH06662: Allowing module loading process to continue for module at /usr/local/opt/php@8.0/lib/httpd/modules/libphp.so because module signature matches authority "Alex Conesa" specified in LoadModule directive
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using Toronto.local. Set the 'ServerName' directive globally to suppress this message
Syntax OK

Reload apache and voilá! Everything works!

$ sudo apachectl restart

Navigate to the http://localhost address in your Mac OS web browser and you will get the Apache default page.

Awesome! Congratulations! You did it!

Sin categoría

Ejecutar programas JavaFX en procesadores ARM (Raspberry Pi)

Si has llegado a este post es porque quieres instalar JavaFX en una Raspberry Pi y Oracle discontinuó el soporte para los procesadores ARM desde la versión JDK 8u33.

Aunque hay mucha literatura contando que no es posible instalarlo, no es cierto. Sí se puede, y funciona perfectamente.

¿Qué necesitas?

1 Raspberry Pi (preferentemente v2 o v3)

1 Linux Raspbian Jessie Lite

1 La última versión disponible de Java JDK 8

1 «Parche»

¿Qué es importante conocer antes de empezar?

En primer lugar, que JavaFX gestiona el modo gráfico «per se». Por lo tanto, NO necesitas instalar una versión completa de Raspbian (o cualquier otra «distro» como Ubuntu, Mate, …) por lo que te ahorrarás la carga de memoria que supone el entorno gráfico X11, pero sí algunos de sus componentes como ya te explicaré más adelante.

JavaFX captura todos los eventos que se producen en el dispositivo. Esto es un poco molesto durante la fase de desarrollo porque no tendrás la posibilidad ni de pulsar Control+C para detener tu programa. Más adelante te explicaré cómo lidiar con este tema.

Por último JavaFX intercepta las llamadas del sistema para desconectar la pantalla (screen blank timer). Para deshabilitar este comportamiento deberás configurar Linux adecuadamente. Más adelante también te contaré cómo.

¡Empecemos!

Descarga Raspbian Jessie Lite e instálalo en una tarjeta SSD

https://www.raspberrypi.org/downloads/raspbian/

Para instalar Raspbian Jessie Lite en una tarjeta SSD bajo Mac OS X te recomiendo que leas este post Install Raspbian Jessie Lite on a SSD (Mac OS X) for using JavaFX on a Raspberry Pi (lo escribí en inglés pero los pasos/comandos se pueden comprender sin problema alguno).

Una vez tengas tu Raspberry Pi funcionando con Raspbian Jessie Lite, vamos a configurarlo para que pueda ejecutar JavaFX.

En primer lugar necesitaremos asignar algunos parámetros del sistema como son la memoria de vídeo compartida, la cual debe ser mayor a la que se informa por defecto. Para ello usaremos el comando raspi-config:

sudo raspi-config

Una vez dentro, modifica los siguientes valores:

En opciones avanzadas establece el valor de la memoria compartida a 256
(Advanced Options / Memory Split)

Opcionalmente asigna "console auto-login" en "Boot Options"
De esta forma la Raspberry arrancará de forma automática sin solicitar user / password.

Ahora necesitamos instalar algunas librerías, por lo que ejecutaremos los siguientes comandos:

sudo apt-get update
sudo apt-get install libpango-1.0-0:armhf libpangoft2-1.0-0:armhf
sudo apt-get install libgtk2.0-0
sudo apt-get install x-window-system

# Y para los que sí quieran un entorno gráfico mínimo (opcionalmente!):
sudo apt-get install xfce4

Ahora sólo nos falta descargar la JVM y un parche mantenido por la comunidad relacionada con OpenJDK, que incluye las librerías (o «blibliotecas» para los más puristas) de JavaFX.

Descarga y configuración de Java JDK:

Si quieres descargar la última versión disponible del JDK y no tienes más medios a tu alcance que la consola de Linux Raspbian (o Ubuntu, Mate, …) te recomiendo que uses el shell script que preparé días atrás y que describe este otro post (Shell script Linux para descargar la última versión de Oracle Java JDK via consola (Raspberry Pi)).

Si sabes cómo copiar el archivo del JDK desde otra máquina en tu red usando el comando scp o cualquier otro, adelante.

En cualquier caso, supondremos que ya tienes el archivo en tu Raspberry. Por lo tanto, procederemos a descomprimirlo, copiarlo en una carpeta determinada (para que el resto de pasos de este tutorial tengan sentido), etc. Supondremos que tienes el archivo correspondiente a la versión 8u141. Si es otro, modifica el nombre a tu conveniencia:

# Nos situamos en la carpeta /home/pi
cd
# Creamos la carpeta jvm donde almacenaremos Java JDK y JavaFX
mkdir jvm

# Descomprimimos el JDK
tar -xf jdk-8u141-linux-arm32-vfp-hflt.tar.gz -C ./jvm

# Esta operación habrá creado la carpeta jdk1.8.0_141 dentro de jvm

A partir de este instante, ya disponemos de Java en nuestra RaspBerry Pi, aunque no aún JavaFX.

Descarga y configuración de JavaFX:

Descargamos el archivo armv6hf-sdk-8.60.9.zip de http://gluonhq.com/download/javafx-embedded-sdk/

wget http://gluonhq.com/download/javafx-embedded-sdk/

Una vez descargado lo descomprimimos dentro de la carpeta jvm:

# Descomprimimos el archivo descargado con uno de estos dos comandos (cualquiera sirve):
unzip armv6hf-sdk-8.60.9.zip -d ./jvm/armv6hf-sdk

tar -xf armv6hf-sdk-8.60.9.zip -C ./jvm

# Esta operación habrá creado la carpeta armv6hf-sdk dentro de jvm

Ahora sí, ya podemos ejecutar JavaFX en nuestra Raspberry Pi sin problema, pero deberemos indicarle explícitamente a la JVM que debe usar las librerías del runtime de JavaFX.

Por ejemplo, para ejecutar un programa JavaFX, almacenado en el archivo mi-test-java-fx-raspberry.jar usaremos el siguiente comando:

./jvm/jdk1.8.0_141/jre/bin/java -Djava.ext.dirs=./jvm/armv6hf-sdk/rt/lib/ext -jar mi-test-java-fx-raspberry.jar

Un saludo y enjoy developing, programming and coding!

NOTA: Te paso un link a una playlist que estoy creando con ayuda de todos los developers y coders que están a mi alrededor. A ver qué te parece! Disfrútala también!

Entradas relacionadas:

Install Raspbian Jessie Lite on a SSD (Mac OS X) for using JavaFX on a Raspberry Pi

Shell script Linux para descargar la última versión de Oracle Java JDK via consola (Raspberry Pi)

Udev: Failed to write to /sys/class/input/mice/uevent Check that you have permission to access input devices on Raspberry Pi

JavaFX on Raspberry Pi error: java.lang.NullPointerException at javafx.scene.text.Font.getDefault(Font.java:86)

Sin categoría

Udev: Failed to write to /sys/class/input/mice/uevent Check that you have permission to access input devices on Raspberry Pi

The «Udev: Failed to write to /sys/class/input/mice/uevent – Check that you have permission to access input devices» occurs when you execute a JavaFX application on a Raspberry Pi using a «normal» user (not root).

The underlying problem is the use that JavaFX do with the device hardware: it requires ‘write’ access to them directly.

To avoid the problem just execute your command using «sudo» or -better- modify the system settings to grant write access to the devices all users that belongs to the «input» group.

To do so just edit the 99-com.rules file:

sudo nano /etc/udev/rules.d/99-com.rules

And paste this script at the bottom of the file:

SUBSYSTEM=="input*", PROGRAM="/bin/sh -c '\
 chown -R root:input /sys/class/input/*/ && chmod -R 770 /sys/class/input/*/;\
'"

Press control+X and save the changes.

Enjoy!

Sin categoría

JavaFX on Raspberry Pi error: java.lang.NullPointerException at javafx.scene.text.Font.getDefault(Font.java:86)

Este error es muy común cuando intentas ejecutar JavaFX en una Raspberry que no dispone de entorno gráfico (X11).

En este escenario JavaFX (más concretamente la clase Font) es incapaz de obtener una lista de las fuentes instaladas en el sistema. Simplemente por que no las hay 🙂

Para evitar este error instala los siguientes paquetes, suponiendo que estás usando Raspbian, Ubuntu, o cualquier otra «distro» basada en Debian:

sudo apt-get update
sudo apt-get install libpango-1.0-0:armhf libpangoft2-1.0-0:armhf
sudo apt-get install libgtk2.0-0
sudo apt-get install x-window-system

 

Para asegurarte que tienes fuentes instaladas puedes usar el comando:

fc-list

A partir de este instante ya podrás ejecutar JavaFX sin problema alguno y olvidarte del fastidioso error:

Caused by: java.lang.NullPointerExceptionCaused by: java.lang.NullPointerException 
at com.sun.javafx.font.PrismFontLoader.loadFont(PrismFontLoader.java:196) 
at javafx.scene.text.Font.<init>(Font.java:319) 
at javafx.scene.text.Font.getDefault(Font.java:86) 
at javafx.scene.CssStyleHelper.<clinit>(CssStyleHelper.java:1528) 
... 19 more

Enjoy!

Sin categoría

Install Raspbian Jessie Lite on a SSD (Mac OS X) for using JavaFX on a Raspberry Pi

Let us see in a few steps how to install Raspbian Jessie Lite, a non X11 graphics environment, on a SSD card in order to use it on a Raspberry Pi.

Keep in mind that it will involve steps to be performed on your Mac and steps to be performed on your Raspberry Pi.

Prepare the SSD card on your Mac OS

First of all we need to download the Raspbian Jessie Lite from its official website: https://www.raspberrypi.org/downloads/raspbian/

Select the .zip version and store it in your Downloads folder (it could be any other folder but I have mentioned this one to be able to describe the further steps accordingly).

Once downloaded the file (2017-07-05-raspbian-jessie-lite.zip in the moment I wrote this article) we just need to unzip it to obtain the .img file.

Now we can open a terminal and type the following commands:

unzip 2017-07-05-raspbian-jessie-lite.zip

Great! We just got the 2017-07-05-raspbian-jessie-lite.img file so it is time to write its contents to the SSD card.

If you know how to deal with external devices such as external hard disks, SSD cards, etc. you can just skip the next step. Otherwise I encourage you to, first of all, take a look to your current devices (prior to plug your SSD to your computer):

diskutil list

Take note of all the device names you got. /dev/disk1, /dev/disk2, … and so on. It depends on how much devices you have connected.

Now it is time to plug your SSD card in your Mac, and after a few seconds, check which is the device name assigned to it:

diskutil list

In my case I got all my storage devices list and this one is the SSD card:

/dev/disk3 (external, physical):
 #: TYPE NAME SIZE IDENTIFIER
 0: FDisk_partition_scheme *16.0 GB disk3
 1: Windows_FAT_32 PI_BOOT 66.1 MB disk3s1
 2: Linux 16.0 GB disk3s2

Unmount the SSD volume using its device name (/dev/diskN) that in my case is disk3:

diskutil unmountDisk /dev/disk3

You must get a «Unmount of all volumes on disk3 was successful» message.

Now it is time to write your .img file to the /dev/diskN volume:

cd
cd Downloads
sudo dd bs=4m if=2017-07-05-raspbian-jessie-lite.img of=/dev/disk3 conv=sync

After a while (it may take long time to be completed!) the dd command must return something similar to this:

411+1 records in
412+0 records out
1728053248 bytes transferred in 908.087166 secs (1902960 bytes/sec)

(This is the time it took in my iMac i7!)

Finally, although it is not a compulsory step, it is better to force a device unmount again:

diskutil unmountDisk /dev/disk3

 

Steps to follow on the Raspberry Pi side

We have a fantastic Raspbian Jessie Lite installed in a SSD card so it is time to plug it in our Raspberry Pi device and turn it on.

I assume that you already know how to do it 🙂 So let us go!

Initially login using the default user and password:

User: pi
Password: raspberry

Execute the Raspberry Pi configuration tool:

raspi-config

Set up the following settings (some of them are optional but I just describe them for your convenience):

Set a new password for the "pi" user (recommended)
Set a valid hostname
Set your localization parameters & eventually change the keyboard layout
Set interfacing options: Enable the SSH server (recommended)
Set advanced options: Expand file system

Once you set all this settings just select «finish» and reboot the Raspberry Pi.

Everything must be fine so you can enjoy using your Raspberry Pi with a Raspbian Jessie Lite installed on it.

Java, Raspberry

Shell script Linux para descargar la última versión de Oracle Java JDK via consola (Raspberry Pi)

¿Quieres saber cómo descargar la última versión del JDK de Java desde la consola de forma automática?

Este artículo lo he escrito a petición de un compañero que necesitaba descargar la última versión disponible del JDK de Oracle en una Raspberry Pi 2 en la que tenía únicamente acceso via consola (sin navegador) en una distribución Raspbian Jessie Lite.

Al tema: no puedes usar el comando «wget» directamente, porque Oracle requiere que «aceptes los términos de licencia» para poder proceder y, además, la página de descarga genera los vínculos a los archivos de forma dinámica.

Por ejemplo, en el momento de escribir este artículo, el link para descargar la última versión de Java JDK 8 para ARM 32 bits es la u141 siendo el link al archivo algo parecido a esto:

http://download.oracle.com/otn/java/jdk/8u141-b15/336fa29ff2bb4ef291e347e091f7f4a7/jdk-8u141-linux-arm32-vfp-hflt.tar.gz

Vemos que el link superior contiene un UID («336fa29ff2bb4ef291e347e091f7f4a7» para el caso) obtenido dinámicamente al cargar la página en el navegador.

Así pues, ¿cómo lo hacemos para descargar el JDK usando el comando «wget» si sólo tenemos acceso a la consola?

En primer lugar crea un archivo en cualquier carpeta de tu disco y llámalo -por ejemplo- download_jdk.sh. Para el ejemplo usaremos el editor «nano».

$ nano download_jdk.sh

Ahora, pega el siguiente contenido:

#!/bin/bash

# Puedes cambiar la versión de Java fácilmente
jdk_version=8

# Obtenemos 32 o 64 (bits)
architecture=$(getconf LONG_BIT)

# Dominio principal para la descarga
domain="http://www.oracle.com"

# Página inicial en la que se generan los vínculos de descarga
main_url="$domain/technetwork/java/javase/downloads/index.html"
downloads_page=$(curl -s $main_url | grep -Po "\/technetwork\/java/\javase\/downloads\/jdk${jdk_version}-downloads-.+?\.html" | head -1)

# Expresión regular para obtener el vínculo al archivo que queremos
expression="http\:\/\/download.oracle\.com\/otn-pub\/java\/jdk\/${jdk_version}u[0-9]+\-(.*)+\/jdk-${jdk_version}u[0-9]+(.*)linux-arm${architecture}-vfp-hflt.tar.gz"

# Obtenemos el link
link_to_file=$(curl -s ${domain}${downloads_page} | egrep -o $expression)

# Nombre del archivo de salida (lo borramos si ya existe)
output_file=jdk-$jdk_version.tar.gz
rm -f $output_file

# Descarga del archivo
wget --no-check-certificate \
 --header "Cookie: oraclelicense=accept-securebackup-cookie" \
 --no-cookies \
 -O $output_file \
 $link_to_file

Guarda los cambios (Control+X, Sí/Yes, ENTER).

Ahora ya puedes ejecutar el script directamente con el comando sh (no requiriendo que asignes el atributo +x si no quieres):

$ sh download_jdk.sh

Voilá! Ya tienes tu archivo jdk-8.tar.gz disponible.

Para descomprimirlo puede usar el comando tar:

$ tar -xf jdk-8.tar.gz

Espero te sea de utilidad.

NOTA: Aunque el script está hecho «ad-hoc» para descargar la versión específica para Raspberry (ARM Hard Float) puedes modificarlo fácilmente para que sirva para cualquier otro JDK.
Por ejemplo para descargar la última versión disponible del JDK para Windows de 32 bits:

expression="http\:\/\/download.oracle\.com\/otn-pub\/java\/jdk\/${jdk_version}u[0-9]+\-(.*)+\/jdk-${jdk_version}u[0-9]+(.*)windows-i586.exe"

Y la de 64 bits:

expression="http\:\/\/download.oracle\.com\/otn-pub\/java\/jdk\/${jdk_version}u[0-9]+\-(.*)+\/jdk-${jdk_version}u[0-9]+(.*)windows-x64.exe"