Destacado

Apache Kafka + Kafka Connect + Emulador de Pub/Sub

Uh… ¿hay alguien aquí? Bueno, al menos soy consistente (no escribiendo). Bienvenidos de vuelta a otro post donde hablo un poco de los problemas que me voy encontrando y de cómo los voy solucionando.
Hoy os traigo un problema que me encontré probando una solución local para probar enviar eventos desde un bus de Kafka a un emulador de Google Pub/Sub con el mínimo dolor posible.

Empecemos por lo básico:

  • Apache Kafka: Tecnología de Apache que consiste en una cola de mensajes asíncrona. Tienes Producers, que envían mensajes a una cola o Topic, y un Consumer, que lee de manera ordenada y asíncrona el Topic. El Topic está ordenado por particiones y offsets y hay algunas consideraciones más, pero esto es lo fundamental.
  • Kafka Connect: Una herramienta para enviar datos desde y hacia Kafka desde sistemas externos. Hay versiones opensource pero yo he trabajado solo con la solución de Confluence, que es quien comercializa soluciones de Kafka para empresas (dando ACLs y cositas varias). Funciona con un motor principal al que se le añaden microaplicaciones hechas en Java que hacen tareas en concreto.
  • Google Pub/Sub: Otra tecnología de cola de mensajes asíncrona. Tienes Publishers que envían información a un Topic y un Subscriber que lee mensajes del Topic. Parecido, ¿eh? Hay más diferencias pero honestamente no controlo mucho sobre ellas ni son importantes para este post.

Okay, queremos conectar los 3 sistemas, y además en local porque somos un poco masocas. Yo ya tengo configurado un entorno en Docker que me levanta un broker de Kafka y un Kafka Connect (algún día, por 2030, os hablaré de mi entorno de WSL + Docker sin Docker Desktop porque es el orgullo de mis amores). Por lo tanto, nos hace falta montar algo para emular un Pub/Sub. Además, necesitamos alguna manera de poder interaccionar con el sistema emulado.

Con diferencia de la solución de Apache, Pub/Sub está pensado para ser puramente cloud, por lo que no es tan sencillo como montarse un on-promise en local y ya. Hay alguien en Google que me tiene aprecio y ha publicado amablemente un emulador para el Pub/Sub integrado en medio de su suite de utilidades.
Como entenderéis, como loco de Docker, paso de instalar a mano y me voy a buscar la vida para montarme una imagen con las utilidades. Afortunadamente, Google nos proporciona la imagen ya hecha.

Por otro lado, el cliente consiste en unas utilidades que dejó Google en un repo de GitHub para interactuar con el emulador. Samaritanos también han hecho una imagen de estas utilidades, pero con el ligero detalle de que están bastante desactualizadas, así que tuve que hacerme un Dockerfile para ponerlo todo un poco al día.

Aquí tenéis lo que hace falta añadir a un docker-compose.yml:

  pubsub-client:
    image: pubsub-python-client:1.0
    container_name: pubsub-client
    links:
      - "pubsub-emulator"
    environment:
      - "PUBSUB_PROJECT_ID=test-project"
      - "PUBSUB_EMULATOR_HOST=pubsub-emulator:8538"
    #command: publisher.py test-project create testTopic
    tty: true 
  pubsub-emulator:
    image: gcr.io/google.com/cloudsdktool/google-cloud-cli:latest
    container_name: pubsub-emulator
    ports:
      - "8538:8538"
    command: gcloud beta emulators pubsub start --host-port=0.0.0.0:8538

Y aquí el Dockerfile para el pubsub-python-client:1.0:

FROM nightfury1204/alpine-curl:latest
RUN /bin/sh
ENV ALPINE_VERSION=3.7
ENV PACKAGES="dumb-init	musl	libc6-compat	linux-headers	build-base	bash	git	ca-certificates	python3	python3-dev"
RUN /bin/sh -c echo   && echo "http://dl-cdn.alpinelinux.org/alpine/v$ALPINE_VERSION/testing" > /etc/apk/repositories   && echo "http://dl-cdn.alpinelinux.org/alpine/v$ALPINE_VERSION/community" >> /etc/apk/repositories   && echo "http://dl-cdn.alpinelinux.org/alpine/v$ALPINE_VERSION/main" >> /etc/apk/repositories   && apk add --no-cache $PACKAGES ||     (sed -i -e 's/dl-cdn/dl-4/g' /etc/apk/repositories && apk add --no-cache $PACKAGES)   && echo "http://dl-cdn.alpinelinux.org/alpine/v$ALPINE_VERSION/main/" > /etc/apk/repositories   && if [[ ! -e /usr/bin/python ]];        then ln -sf /usr/bin/python3 /usr/bin/python; fi   && if [[ ! -e /usr/bin/python-config ]]; then ln -sf /usr/bin/python3-config /usr/bin/python-config; fi   && if [[ ! -e /usr/bin/pydoc ]];         then ln -sf /usr/bin/pydoc3 /usr/bin/pydoc; fi   && if [[ ! -e /usr/bin/easy_install ]];  then ln -sf $(ls /usr/bin/easy_install*) /usr/bin/easy_install; fi   && easy_install pip   && pip install --upgrade pip   && if [[ ! -e /usr/bin/pip ]]; then ln -sf /usr/bin/pip3 /usr/bin/pip; fi
ENTRYPOINT ["/usr/bin/dumb-init"]
RUN "python"
RUN apk add git
RUN git clone https://github.com/googleapis/python-pubsub
WORKDIR /python-pubsub/
RUN git checkout tags/v2.12.1 -b current
WORKDIR /python-pubsub/samples/snippets
RUN pwd
RUN ls 
RUN pip install -r requirements.txt
ENTRYPOINT ["python"]

¿Okay, pues listo, no? Levantamos el bus, el Connect, el cliente y el emulador, creamos topics en los dos buses, enchufamos eventos al bus y creamos un conector para enviarlos a Pub/Sub.
Pues no va.

Okay, ¿cuál es el problema? Resulta que el emulador es bastante especialito con cómo quiere recibir los eventos, y el conector también se las trae. Primero, el conector de base no admite el hecho de que no haya autentificación (lo cual hace falta para enviar eventos al emulador). Segundo, el emulador hace un handshake SSL incompatible con el sistema cloud (what. the. fuck.) por lo que tienes que establecer un canal de comunicaciones entre el cliente y el emulador sin cifrar, lo cual obviamente tampoco soporta el conector.
Está todo descrito en esta página:

Pues toca abrir el conector y tocar estas cosillas. Afortunadamente para vosotros, ya lo he hecho para vosotros (al menos en el caso de un conector Kafka –> PubSub) y lo tenéis disponible en este repo de GitHub.

[...]

 gcpCredentialsProvider = NoCredentialsProvider.create();

[...]

  private void createPublisher() {
    ProjectTopicName fullTopic = ProjectTopicName.of(cpsProject, cpsTopic);
	ManagedChannel channel = ManagedChannelBuilder.forTarget(cpsEndpoint).usePlaintext().build();
	TransportChannelProvider channelProvider = FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel));
	
	com.google.cloud.pubsub.v1.Publisher.Builder builder = 
		Publisher.newBuilder(fullTopic)
			.setChannelProvider(channelProvider)
			.setCredentialsProvider(gcpCredentialsProvider);
    try {
      publisher = builder.build();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }


Recomplilas el conector, lo pones en el Connect, reintentas y ¡voilà! Eventos de Kafka a PubSub. Afortunadamente, los problemas del emulador no los sufres en un entorno real, porque el conector se conecta sin problema a Google, suponiendo que no tengas mucho firewall dando problemas por en medio (lo cual puede ser un problemilla, ya que el conector no admite de manera nativa ningún tipo de conexión por proxy, así que te la tienes que picar a manini).

Hasta aquí mi historia de hoy. Nos vemos quien sabe cuando para hablaros de otras cosas totalmente irrisorias que me asolan en el curro.
¡Chao!

Destacado

Cómo recuperar un long de HBase y no morir en el intento

¿Recordáis cuando iba a intentar ser consistente a la hora de escribir en el blog? .

En fin, hoy os vengo a hablar de un detalle que me rompió la cabeza durante una temporada y he conseguido solucionar de manera relativamente eficaz:

Quien haya trabajo con HBase y su shell, se habrá encontrado con los siguientes datos alguna vez:

ROW            COLUMN+CELL
111222333      column=FAM1:ID, timestamp=1611977689866, value=111222333
111222333      column=FAM1:DAT1, timestamp=1611977689866, value=DAT1
111222333      column=FAM1:DAT2, timestamp=1611977689866, value=\x00\x00\x01t\xD1\x93\x1Fp

¿Y qué demonios es lo que pone ahí? Vais a vuestro código que se ha encargado de insertar un registro en HBase y véis que lo habéis guardado como un Long (que en Java ocupa 8 bytes)… pero eso no son 8 bytes.

Sin embargo, podéis encontrar los bytes de vuelta si se ven de la siguiente manera:

\x00 \x00 \x01 t \xD1 \x93 \x1F p

Resulta que como muestra la información por pantalla HBase es mediante arrays de caracteres que además no son «type-aware», y resulta que escapa en hexa todos los caracteres que son ASCII imprimible, y deja tal cual caracteres que no puede imprimir. Si miramos qué rango de caracteres se encuentra dentro de ASCII imprimible, vemos que son 128 caracteres (00 a 7F), pero sospecho que no transforma caracteres de 00 a 1F ya que son símbolos de control, usando realmente 20 a 7F. Básicamente, si puede pasarlo a ASCII imprimible, pasará el byte a ASCII, y si no puede, lo dejará en hexa.

Vamos a hacer el ejercicio de pasar a mano a transformar de vuelta estos bytes al long original, primero pasando a un array de bytes unsigned en decimal:

\x00 --> 00h, 000d
\x00 --> 00h, 000d
\x01 --> 01h, 001d
t    --> 74h, 116d
\xD1 --> D1h, 209d
\x93 --> 93h, 147d
\x1F --> 1Fh, 031d
p    --> 70h, 112d

Quedándonos el array siguiente:

[0,0,1,116,209,147,31,112]

Solo nos quedaría multiplicar los valores por su término correspondiente (hacer un shift de bytes):

000*2^(7*8) --> 0
000*2^(6*8) --> 0
001*2^(5*8) --> 1099511627776
116*2^(4*8) --> 498216206336
209*2^(3*8) --> 3506438144
147*2^(2*8) --> 9633792
031*2^(1*8) --> 7936
112*2^(0*8) --> 112

SUM = 0 + 0 + 1099511627776 + 498216206336 + 3506438144 + 9633792 + 7936 + 112 = 1601243914096

A los que estén relativamente puestos con tiempo Unix, verán que es un triste timestamp en ms (en concreto del 27 de noviembre de 2020).

Pero hacer esto a mano es un poco infierno. ¿Seguro que hay alguna manera de hacer esto programáticamente, verdad? Pues os traigo 2 soluciones de mi propia cosecha, 1 en JavaScript y otra en Scala, donde introduciendo el string que nos da HBase nos devuelve el querido long. Cada implementación tiene sus características (JavaScript no se lleva excesivamente bien con trabajar a nivel de byte, y hay que tirar de un ArrayBuffer, y hay que tener cuidado con que si es unsigned o signed bytes, ya que para Java sus primitivos son con signo), pero hacen bastante bien su trabajo. Os lo dejo a continuación.

JavaScript:

function toBytes(array){
    
    var arr = new ArrayBuffer(8);
    var view = new DataView(arr);
    for (i in array) {
        view.setUint8(i, array[i], false);
    }
    return view.getBigInt64();
}

function expandHBaseHex(input){
    if (input.length > 2){
        var p1 = input.substr(0,2);
        var p2 = input[2].charCodeAt(0);
        return [parseInt("0x"+p1), p2]
    }
    else return [parseInt("0x"+input)]

}

function HBaseHexToString(str){

    var a = str.replace(/\\x/, "").split("\\x");
    console.log(a);
    var b = a.flatMap(expandHBaseHex);
    console.log(b);
    var c = toBytes(b);
    return c;
}

HBaseHexToString("\\x00\\x00\\x01t\\xD1\\x93\\x1Fp") // escapar las barras que si no lo entiende como hexa

Scala:

import java.nio.ByteBuffer

def HBaseHexToBytes (str: String) = {
val t1 = str
.replaceFirst("^\\\\x", "")
.split("\\\\x")
.flatMap{ x =>
	if (x.length > 2) { // tiene parte de hex + parte char
		var p1 = x.substring(0,2)
		var p2 = x.apply(2).toHexString
		Seq(Integer.parseInt(p1,16),Integer.parseInt(p2,16))
		}
	else Seq(Integer.parseInt(x,16))}
t1.map(_.toByte)
}

def transformHBaseHexToLong(str: String) = ByteBuffer.wrap(HBaseHexToBytes(str)).getLong()

transformHBaseHexToLong("\\x00\\x00\\x01t\\xD1\\x93\\x1Fp")

¡Y hasta aquí el artículo de hoy! Espero que os haya sido de utilidad, y si no, pues que al menos os resulte interesante. ¡Hasta la próxima!

Enlacemanía [I]

A ver como explico esto.

Por las -1 personas que todavía recuerden que mi blog existen, habrán notado que no hago un uso exhausto de él, ni se puede decir que sea la obra de literatura más extensa que se haya escrito. Llevo tiempo queriendo escribir en él, pero nunca he sabido en qué pudiera orientar distintos artículos sin tampoco meterme mucho al trapo pero intentando dar un poco de luz en los temas más oscuros donde me esté metiendo (aunque sea obvio para algunos otros). Así que se me ha ocurrido esta idea: Escribir los findes de los artículos más interesantes que me haya encontrado durante la semana de la que trabajo. Si durante una semana no saco suficiente chicha para otro post (eso es que he tenido una semana tranquila) lo acumularé y lo sacaré eventualmente. Espero que le sirva a alguien tanto como me sirvieron a mí, supongo. Allá vamos:

Aviso: el contenido de los artículos está bastante relacionado con Java, Scala y Spark.

  • Resulta que en Scala no es lo mismo un Int (es la definición interna de Scala de un entero, scala.Int) que un Integer (que es el clásico java.lang.Integer). Aunque por lo general hay conversiones de manera implícita, parece que usando Option[] esta conversión no se la traga Java, lo cual es curioso, parece que tiene que ver con el tratamiento que hace Spark de las case classes para inferir el schema para los DataFrames. [Link]
  • Me hacía falta comprobar si un string era todo dígitos o no, y éste método me pareció bastante sencillo. [Link]
  • Por shenanigans probé a unir un Dataset de Spark Batch y Structured Streaming. Spoiler: no funciona [Link] [Link]
  • En HBase puedes hacer un get de una fila en concreto o un scan que analiza en una tabla las filas que te hagan falta. Aunque en principio intenté hacer un scan eficiente delimitando el principio y el fin de los rows a buscar, parece que sigue siendo x10 más rápido tirar de un get. Este link en concreto contradice lo que acabo de decir, pero me imagino que dependerá del número de regiones de tu HBase y otros detalles técnicos que escapan a mi entendimiento. [Link variado]
  • Sabéis AWK? Bueno, existe esto. Ya me lo agradeceréis.
  • Estuve intentando comprender cómo iba el tema de logging y log4j en Scala, y resulta que es que en cada clase te creas el log correspondiente a esa clase e informas desde ahí con tus warn y tus info. ¡Y yo pensando que usabas un solo logger! Lo hace bastante cómodo porque el propio logger te informa de su clase y tal. TheMoreYouKnow™ [Link]
  • Y por último, os dejo una línea de la expresión más bonita que he visto en mucho tiempo en programming:
Flatteneando con estilo

¡Hasta aquí el artículo de hoy! Nos vemos pronto. ¡Chao!

Protip: vscode, CLRF y scripts de Bash

¡Hola!

¿Has intentado alguna vez hacer un export en un script de bash? ¿No te funciona?

¿Haces «export» en el terminal y te sale algo como esto?

$ export
-- LO QUE SALE
"eclare -x TEST1="mequieropegaruntiro
"eclare -x TEST2="mequieropegarotrotiro
-- LO QUE DEBERIA SALIR
declare -x TEST1="mequieropegaruntiro"
declare -x TEST2="mequieropegarotrotiro"

¡No te preocupes! Soy tú 3 horas en el futuro, con la solución en la mano.

Resulta que tu editor favorito de texto (en mi caso vscode) pone a default la línea nueva como CRLF (Carriage Return, vuelve al comienzo de la línea + Line Feed, salta a la siguiente línea). PUES NO LE GUSTA CR EN LOS SCRIPTS MUCHO A BASH, FÍJATE TÚ.

¿Solución? Asegurarse que tu editor sólo pone LF en línea nueva ya sea viendo estos caracteres en el editor (eso es para tí enfermo del Notepad++) o en vscode selecciona la opción de LF abajo a la derecha, según relata la siguiente imagen:

tilt over 9000

Si he llegado a tiempo, estás bailando de alegria y llenos de ilusión, y disfrutarás feliz del fin de semana. O puedes haber llegado tarde. Bienvenido al club.

¡Nos vemos!

PPWT Londres, SQLSat Madrid ‘19 y ¿ahora qué?

¡Buenas! 

Como sabéis, soy un desastre manteniendo este blog y mantener un registro de lo que hago me resulta imposible, así que ¡voy a intentar ponerme un poco al día! 

Durante este verano he ido a 2 eventos como speaker: 

Power Platform World Tour @ London, 2019 

En este evento me aceptaron junto con @ambynet una charla acerca de la integración de Python y R en Power BI de manera local, lo cual otorga nuevas funcionalidades a la herramienta, desde descomprimir un zip hasta correr sklearn en local y portar los datos como un paso de PowerQuery. 

Fue en la zona de Borough, en Londres, durante dos días. Hubieron speakers de altísimo nivel y de todas partes del mundo, desde Jen Stirrup con AI hasta Will Thompson junto con otros miembros del equipo de producto, hablando de tú a tú con líderes de la comunidad y respondiendo a respuestas candentes en cuanto al desarrollo y futuro de la herramienta.  

Estuvo muy bien organizado, numerosos tracks y local excelente. Un placer haber podido tener la oportunidad de dar una charla en un evento de tal calibre, e intentaré sin duda asistir a la próxima edición, si no otro evento antes. 

SQL Saturday Madrid, 2019 

Qué se puede decir que no se haya dicho ya del Saturday de Madrid, aparte del increíble salto en calidad con respecto al año pasado. El traspaso a la Politécnica y a la ETSI ha mejorado las instalaciones del evento sobremanera, y aunque hubo intentos de complicarse las charlas (Internet en las universidades suele ser una complicación desde el punto de vista de seguridad) todo se planeó correctamente y todo aquel que necesitó, tuvo. 

Aquí tuve la oportunidad de hablar de la integración de Web y el uso de APIs para usar aplicaciones Web, con el objetivo de quitarle el miedo en el cuerpo a la gente acerca de estos temas. Aparte, tuvimos muchos gansos y muchos juegos, así que intenté que fuera lo más entretenida posible. 

La organización excelente, y la calidad de los speakers brutal. Desde charlas sobre las novedades de SQL Server 19 hasta Churn Norris, un evento para todos los públicos del mundo de los datos, donde en cualquier sesión te puedes llevar algo, te sea conocido el tema o no. 

Destacar la sesión de Woman In Tech, un grupo de usuarios pero sobre todo usuarias con el objetivo de empoderar el papel de speakers en el mundo femenino, que lamentablemente sigue a unos niveles totalmente desbalanceados, y aspira a aspirar al gran porcentaje de población femenina que asiste al evento a dar una charla y a abrirse paso en la comunidad, que son indispensables ideas y puntos de vista de todos los géneros. 

Aparte, agradecer la labor de los voluntarios por parte de la Universidad Politécnica, que han sido maravillosas personas con las que trabajar, y que aprovechen este entusiasmo que han tenido a la hora de ayudarnos a organizar el evento para animarse ellos a apuntarse a la comunidad de PASS y donde quieran, que ni la edad y la experiencia son problemas, y si no un servidor, que es un desvergonzado (afortunadamente para bien) 

Saludos a todos y cada uno de los que contribuyen a que este evento sea posible, y nos vemos el año que viene con más Saturday (¡quizás antes de septiembre y todo!) 

— 

Me la he pasado piruleta y agradezco mucho todas las muestras de apoyo y fe que se han depositado en mi persona para estos 2 eventos, y ahora toca trabajar para merecerme otra subida al escenario. 

En cuanto a lo que voy a poner por aquí, este es el plan a corto-medio plazo: 

  • Escribir artículo/s acerca de la charla de R y Python (con documentación de la charla) 
  • Escribir artículo/s acerca de la charla de Web (con documentación) 
  • Mantener un poco menos seco el blog y escribir desde cosillas rápidas hasta artículos más extensos (la carpeta de Chrome con cosas para escribir va en los cientos, y sólo pegarse con cosas del trabajo da para un libro) 

Pero bueno, eso para otro día. 

¡Nos vemos! 

VSCode & WSL en Win10

Por motivos del azar he tenido que trabajar con archivos de texto plano de varios MB de tamaño y ni Notepad++ ni nuestro abandonware favorito Sublime han podido dar la talla, y decidí probar VSCode. TL;DR funciona espectacular para cualquier cosa que se os ocurra, y cuando sea mayor y un poco menos terrible con la gestión de mi tiempo libre estudiaré sus virtudes y sus grandezas y las pondré por aquí.

Hoy voy a hablar de un caso muy bonito: el poder tener en la terminal de VSCode una sesión de WSL para que podamos ahí hacer nuestros CMakes y nuestras cosas chulis de Bash pero en el entorno de Windows 10.

Esto que voy a contar viene perfectamente explicado en la siguiente página pero para los no excesivamente dichos en inglés aquí os va un resumen corto:

  1. Tened WSL descargado y configurado (duh). Tened cuidado si tenéis varias distros, ya que se usará la predeterminada.
  2. Os hace falta también VSCode Insiders, la versión beta de VSCode pero no os preocupéis que trabaja en paralelo a VSCode, con distintas extensiones y configuración así que vuestras cosas de VSCode se quedan sin tocar. (añadid Insiders al PATH durante la instalación que después se hace más sencillo todo)
  3. Instalad la extensión Remote Development en Insiders (tened cuidado que el navegador os va a abrir solo seguramente VSCode normal, y que esta extensión solo funciona en Insiders)
  4. Abrid VSCode Insiders, váis al terminal y al workspace que queráis usar. Ahí introducís wsl para que se ejecute el subsistema y ya en él ponéis code-insiders .(importante el punto del final, indica que se abra en ese working directory). Si todo va bien os va a ejecutar una nueva ventana donde tendréis en remoto el sistema WSL en el workspace que habéis mandao, y tenéis todo listo para rockear. Si code-insiders no os funciona en el Terminal, es que no me habéis hecho caso e Insiders no está en el PATH. Lo podéis arreglar invocando con F1 al buscador y abriendo una nueva ventana de Remote-WSL, pero es mucho menos estiloso. Os dejo un GIF muy riquín donde podéis ver este paso.

¡Y ya estaría! Tenéis todas las características de VSCode en Win 10 pero en un entorno de desarollo local de Linux, ¡qué más se le puede pedir a la vida!

Hay algunos ligeros issues puestos en la página de WSL con ciertas aplicaciones (Git de vez en cuando se marea, Node.js + Firebase le cuesta arrancar, etc) pero para el 97% de los casos debería iros perfecto. Para más detalle mirad la documentación oficial. Para volver de la sesión en remoto, solamente teneís que abrir una nueva ventana de Insiders (CTRL+Shift+N de toda la vida) y ya estáis fuera de WSL, aunque me imagino que si no usabais Insiders antes simplemente abriréis Code normal. Además, como en Code cuando abráis Insiders de nuevo abre la última ventana que habéis cerrado, así que suele cargar vuestra sesión de WSL en remoto para que sea totalmente seamless la experiencia. ¡GUD!

Esto es todo por hoy!

EDIT: para mi yo futuro, en WSL la ruta de acceso a los archivos de Windows está en $/mnt. You’re welcome.

Shared Folders & Hyper-V: howto

¡Hola! Después de 2398 años sin subir artículo, hoy toca hablar un poco de cómo conseguir un folder compartido entre tu host de máquinas virtuales Hyper-V y tus máquinas cliente.

Ya hablaré en otro momento de porqué estoy usando Hyper-V o porqué me es tan conveniente, pero por hoy vamos a intentar solucionar este problema que tenemos.

Tal como viene predeterminado, el adaptador de red ya hace un buen trabajo metiéndote tanto dentro del dominio local como a la red propia del host, por lo que no hace falta tocar nada. El comienzo es crear en donde queramos una carpeta que se va a compartir en el host, y darle permisos de sharing:

Así, damos a un usuario permisos compartidos. Ahora, dentro de la máquina cliente, vamos a crear una nueva ubicación de red que apunte a la carpeta que acabamos de crear. Nota: para conocer cómo acceder a esta carpeta podemos acceder a sus propiedades y en «Compartir» ver la dirección:

Mirar aquí qué dirección hay que poner

Aquí necesitaréis iniciar sesión con el usuario y contraseña de la cuenta host. Nota: recalco contraseña, me daba problemas para conectar a mi cuenta host si ésta no tenía contraseña predeterminada, por lo que yo de vosotros pondría una contraseña a vuestra cuenta.

Y con esto, ¡ya tenéis una carpeta compartida! (Se puede cambiar el nombre antes de confirmar)

Con este pequeño pero espero que útil artículo, espero que os vaya bien a la hora de añadir carpetas compartidas en vuestras soluciones Hyper-V :^)

Windows 10 y entrada por pen: cómo no morir

Recordatorio rápido: en el caso de que estemos usando un tablet con Windows 10 y entrada manuscrita (ej. Surface) recordad que hay una opción muy conveniente de deshabilitar: que no acepte entrada táctil si hay entrada de pen en ese mismo momento para que no te pille la palma de la mano de la que escribes.

Se encuentra buscando Windows Ink o Configuración del Lápiz, y es una de las opciones. Aparte podeis elegir si sois zurdos o diestros y otros detalles útiles.

Programación en C  | Tamaños de arrays y sizeof()

¿Nunca te has preguntado porqué main está definido como «int main(int argc, char** argv)» ? Es decir, si nos dan directamente un array con los valores de los argumentos, ¿no es más sencillo correr un bucle y usar un sizeof como delimitador?

¡Pues resulta que no! Al parecer sizeof solo funciona para encontrar la longitud del array si lo aplicas al array original, pero sin embargo si intentamos hacer el sizeof de un puntero, sizeof devolverá el tamaño del puntero y no del array. Por lo tanto, ¡cuando pedimos la longitud del array como argumento (argc) es necesario y no redundante!

Sin embargo, ya que argv termina convenientemente en un puntero a NULL se puede jugar un poco alrededor de esto, pero de todas maneras no es buena praxis, siendo lo estándar llevar en otra variable o en una estructura una indicación del tamaño de un array decaido a puntero.

¿Dónde está /root en el subsistema de Linux de Windows 10?

Siguiendo con el repost que os puse el otro día sobre instalar Ubuntu en Windows 10, hoy os traigo un truco bastante sencillo para ubicarse y navegar con el explorador de Windows: saber donde está root!

Según este rico y nutritivo artículo de askubuntu, se ve que root se encuentra en

C:\Users\Username\AppData\Local\Lxss\rootfs

cambiando «Username» por vuestro usuario obviamente.

Así podéis mover carpetas y archivos como si estuviérais en el Windows clásico y después interactuar con ello dentro de Bash.

Saludos!