Quantcast
Channel: Planeta Código
Viewing all 2708 articles
Browse latest View live

Picando Código: R-Ladies Madrid y NoLegalTech: Legal Analytics para democratizar el acceso a las leyes

$
0
0

Les dejo la información del próximo evento de R-Ladies Madrid y NoLegalTech en Madrid, a realizarse el martes 20 de noviembre. Todo lo que ayude a democratizar el acceso a información del estado y le de poder a la gente sobre sus gobernantes es bueno:

 R-Ladies Madrid y NoLegalTech: Legal Analytics para democratizar el acceso a las leyes

A la democracia le ha llegado la hora tecnológica

El Boletín Oficial del Estado (BOE) es el diario oficial para la publicación de las normas y las leyes en el territorio español. Recogida en el artículo 9 de la Constitución, la publicidad de las normas es un principio básico de seguridad jurídica de los ciudadanos. Solo, pues, si los ciudadanos conocen las normas pueden ejercer sus derechos y deberes dentro de la sociedad.

Si bien este principio nace como esencial en una sociedad democrática, hoy en día la cantidad de normas aplicables en tiempo y lugar se ha multiplicado hasta tal punto que ni la profesión del abogado puede llegar a alcanzarlas en su plenitud. Desde las directivas y reglamentos que dicta la Unión Europea, hasta las diversas normas que pueden dictar tanto las Cortes Generales como el propio Gobierno (Leyes Orgánicas, Leyes Ordinarias, Reales Decretos…) el puzzle del sistema legal español llega a ser incomprensible bajo los sistemas tradicionales de ejercer la profesión.

En los últimos años el Estado de Derecho, empleando una estructura burocrática alejada del ciudadano y un lenguaje ininteligible e incluso enigmático, se ha ido alejando cada vez más del objetivo principal de la sociedad: la convivencia normativa y la sujeción de los poderes públicos a la norma.

Sin embargo, con la irrupción de la tecnología en nuestras vidas y la generación de datos a lo largo y ancho del globo, el estudio y el aterrizaje de las normas al ciudadano ya es posible.

Habiéndose generado en los dos últimos años más datos que en toda la historia de la humanidad, a través del machine learning y el entrenamiento de textos jurídicos masivos (leyes, normas, disposiciones…), se puede crear lo que por primera vez en España puede traer poder legislativo: conocimiento real de las leyes a través de la ciencia y al margen de los intereses políticos. Hoy en día podemos alcanzar a conocer la normativa vigente española (tan solo conocer qué normas y qué preceptos están en vigor en todas las ramas del Derecho ya es un paso adelante), detectar incompatibilidades normativas… e incluso comprobar, con un análisis social, si una ley es efectiva en el tiempo y lugar en que se ha aplicado.

El próximo 20 de noviembre, bajo el paraguas de la comunidad R-Ladies Madrid y NoLegalTech, celebramos el primer evento Legal Analytics, donde tendrán cabida todas estas cuestiones.

Programa

18:00 Presentación
18.30 Bárbara Román (Nolegaltech): charla “Panorama legal y datos”
19.30 Mesa redonda moderada por Bárbara Román: Gloria Sánchez (Banco Santander), Sara Molina (Marketingnize) y Elen Irazábal (R-Law Geeks)
20.30 Presentación del grupo R-Law Geeks. Será una presentación tanto jurídica como técnica, como un ejemplo de legal analytics.
21.15 Preguntas
21.30 Despedida

Más información e inscripciones


proyectos Ágiles: Refactorización organizativa Agile – Parte 2

$
0
0

Variable not found: Enlaces interesantes 338

$
0
0
Enlaces interesantes
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET / .NET Core

ASP.NET / ASP.NET Core

Azure / Cloud

Conceptos / Patrones / Buenas prácticas

    Web / HTML / CSS / Javascript

    Visual Studio / Complementos / Herramientas

    Xamarin

    Otros

    Publicado en: www.variablenotfound.com.

    Variable not found: Vistas precompiladas y editables en ASP.NET Core MVC 2.1: lo mejor de los dos mundos

    $
    0
    0
    ASP.NET Core MVCSeguramente habréis notado que en proyectos ASP.NET Core 2.1 la compilación de las vistas funciona de forma ligeramente diferente a como se hacía en versiones anteriores. Hasta ahora las vistas sólo eran compiladas al publicar el proyecto pero, a partir de esta versión, este proceso se realizará antes, durante la compilación.

    En este artículo vamos a ver cómo aprovechar las ventajas de la precompilación, y al mismo tiempo mantener la flexibilidad que nos ofrece la compilación en tiempo de ejecución que tradicionalmente hemos disfrutado en proyectos ASP.NET y ASP.NET Core.

    A partir de ASP.NET Core 2.1, cuando compilemos normalmente nuestros proyectos, en el directorio /bin encontraremos, además de los archivos habituales, un ensamblado llamado [MyProjectName].Views.dll con el resultado de la compilación de las vistas Razor:

    Directorio de salida de compilación, con el ensamblado de las vistas

    Esto es buena cosa, sin duda. El hecho de compilar las vistas hará posible que detectemos antes los errores de programación, y normalmente los tiempos de compilación son tan rápidos que ni notaremos que ese proceso se está realizando. Además, al desplegar el proyecto, el arranque de la aplicación será más rápido porque no será necesario compilar las vistas al vuelo cuando los usuarios accedan a ellas.

    Por otra parte, dado que el resultado de la compilación de las vistas ya lo tenemos en la carpeta de binarios en forma de ensamblado, al publicar el proyecto no se incluirá el contenido de las carpetas /Views, /Pages u otras relacionadas con las plantillas Razor:
    Carpeta de resultados de publicación, donde no aparecen las carpetas de vistas

    Gracias a esto, el paquete de publicación será más pequeño y las operaciones de despliegue serán más rápidas, porque hay muchos menos archivos que gestionar.

    Sin embargo, al no existir en el servidor, dejaremos de tener la capacidad de actualizar directamente los archivos Razor, una característica muy socorrida cuando detectamos pequeños fallos o queremos introducir mejoras que no requieren un despliegue completo.

    Lo que realmente estaría bien sería tener lo mejor de estos dos mundos, es decir, disponer al mismo tiempo de las ventajas de publicar las vistas precompiladas, pero a la vez mantener la posibilidad de actualizarlas directamente en el servidor y que éstas fueran recompiladas automáticamente sin necesidad de subir todo el proyecto.

    Para conseguirlo, necesitaremos dos cosas:
    • Primero, hacer que en el paquete de publicación se incluyan los archivos de vista.
       
    • Segundo, hacer que las vistas puedan sean recompiladas de forma automática cuando se detecten cambios en ellas.

    1. Incluir las vistas en el paquete de publicación

    Para que las vistas de una aplicación MVC sean incluidas a la hora de generar el paquete de publicación, basta con añadir el siguiente código al archivo .csproj de nuestro proyecto:
    <ItemGroup>
    <_CustomFiles Include="$(MSBuildProjectDirectory)/views/**/*" />
    <DotnetPublishFiles Include="@(_CustomFiles)">
    <DestinationRelativePath>views/%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
    </DotnetPublishFiles>
    </ItemGroup>
    Si además queremos incluir las páginas Razor, presentes por convención en la carpeta "/Pages" del proyecto, debemos añadir adicionalmente el siguiente bloque:
    <ItemGroup>
    <_CustomFiles Include="$(MSBuildProjectDirectory)/pages/**/*" />
    <DotnetPublishFiles Include="@(_CustomFiles)">
    <DestinationRelativePath>pages/%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
    </DotnetPublishFiles>
    </ItemGroup>
    Obviamente, deberíamos incluir de la misma forma otras carpetas de archivos Razor de nuestro proyecto, por ejemplo si estamos utilizando áreas, o si hemos modificado las convenciones de ubicación.
    Al completar la publicación, si ejecutamos nuestro proyecto veremos que todo funciona correctamente, pero si intentamos modificar alguno de los archivos Razor incluidos en el despliegue y accedemos a él desde el navegador, obtendremos un error como el siguiente:

    Error de compilación al modificar una vista en tiempo de ejecución

    Este error indica que el servidor no dispone de los componentes necesarios para compilar las vistas, veamos cómo solucionarlo.

    2. Hacer que las vistas puedan ser compiladas al vuelo

    De nuevo, la forma de solucionarlo va a ser muy sencilla. Basta con añadir la propiedad <CopyRefAssembliesToPublishDirectory> con el valor "true" en el archivo del proyecto:
    <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <CopyRefAssembliesToPublishDirectory>true</CopyRefAssembliesToPublishDirectory>
    </PropertyGroup>
    Al hacerlo veremos que nuestro paquete de publicación crece considerablemente (en una aplicación casi vacía con la que estoy probando, pasa de 6 a 33MB), pero ya se estarán incluyendo todos esos componentes que faltaban para hacer la compilación posible.

    ¡Y esto es todo! Espero que el truco os resulte útil para aplicarlo en vuestros proyectos.

    Publicado en Variable not found.

    Fixed Buffer: Como instalar .NetCore en Linux

    $
    0
    0

    .NetCore en Linux

    Después de tantas entradas hablando sobre .NetCore y lo que me gusta utilizar una herramienta multiplataforma, hoy vamos a ver como instalar el SDK de .NetCore en Linux. Esto puede parecer algo complicado, pero en realidad es muy muy fácil. En este caso, vamos a utilizar para el ejemplo una distribución Debian 9.5.

    Instalando .NetCore en Linux

    En primer lugar, es necesario instalar el paquete “apt-transport-https”, el cual nos permite conectar con los repositorios de Microsoft:

    sudo apt-get install apt-transport-https

    Después, vamos a registrar las claves de Microsoft dentro de el registro de claves seguras, de cara a que no nos de advertencias al utilizar HTTPS los repositorios, para ello, escribimos las siguientes instrucciones en la terminal (En caso de no utilizar Debian sino otra distro, puedes consultar las instrucciones aquí):

    sudo wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg –dearmor > microsoft.asc.gpg
    sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
    sudo wget -q https://packages.microsoft.com/config/debian/9/prod.list
    sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
    sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
    sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list

    Una vez hecho esto, ya hemos añadido los repositorios a nuestra maquina, con lo cual, solo nos queda actualizar la lista e instalar el SDK:

    sudo apt-get update
    sudo apt-get install dotnet-sdk-2.1

    Con estos sencillos pasos, ya tenemos el SDK instalado en nuestro equipo con Debian, y podemos empezar a trabajar con el.

    Probando el SDK

    Una vez tenemos el SDK instalado, vamos a comprobar que todo funciona correctamente, para ello, vamos a descargar el proyecto de las entrada Venciendo el miedo a las pruebas unitarias en .Net , pero también podríamos hacerla con Rompiendo limites: Mocking en las Pruebas Unitarias .Net o cualquiera de las que usan .NetCore.

    *NOTA: Voy a asumir que no todo el mundo usa git, por los que utilizaré los enlaces https, en caso de hacerlo con git, simplemente seria necesario hacer un “git clone” en vez de una descarga wget.

    Vamos con el primero, lo primero, es descargarlo, descomprimirlo y entrar al proyecto:

    wget https://github.com/JorTurFer/PostPruebasUnitariasCore/archive/master.zip
    unzip -a master.zip
    cd PostPruebasUnitariasCore-master

    Una vez dentro de la carpeta, vamos a construir el proyecto con:

    dotnet build *.sln

    Si todo va bien, veremos algo como esto:

    build result

    Y vamos a comprobar que las pruebas unitarias se ejecutan correctamente accediendo a ellas y ejecutándolas con:

    cd PruebasUnitarias
    dotnet test *.csproj

    Lo que nos debería mostrar algo como esto:

    test result

    En próximas entradas, mostraré como instalar nuestros programas como servicio .NetCore en Linux.

    **La entrada Como instalar .NetCore en Linux se publicó primero en Fixed Buffer.**

    Picando Código: Rust Latam Montevideo 2019 – Conferencia latinoamericana de Rust

    $
    0
    0

    Santiago Pastorino anunció en el foro de Rust información sobre la conferencia Rust Latam 2019.

    Rust Latam Montevideo

    La primera edición de Rust Latam se va a realizar los días 29 y 30 de marzo de 2019 en Montevideo, Uruguay. Del sitio (traducción mía):

    La Conferencia Rust Latam es el evento líder en América Latina por y para el movimiento Rust, y una de las oportunidades anuales más grandes de networking en la comunidad local de Rust. Esta conferencia de un fin de semana con sesiones interactivas, actividades prácticas, y charlas junta a más de 200 defensores, desarrolladores y entusiastas del lenguaje de programación Rust de todo el mundo. En marzo, la gente e ideas de la comunidad latinoamericana de Rust saltará de la pantalla para aprender, discutir, debatir y enfrentar Rust en persona. Nuestra primera conferencia Rust Latam anual empieza en Montevideo.

    En marzo, tendremos ese mismo espíritu vehemente de las reuniones locales. También tendremos a la gente y recursos para hacer un gran impacto. Una conferncia de dos días – series de talleres y oradores – con decenas de expertos y principiantes significa que podemos avanzar el pensamiento en cómo tú y tu equipo pueden usar características de Rust para crear una amplia gama de nuevas aplicaicones de software, como motores de juegos, sistemas operativos, sistemas de archivos, componentes de navegadores web y motores de simulación para realidad virtual. Podemos forjar nuevas sociedades, podemos entrenar a los programadores del mañana y podemos alimentar a la construcción comunitaria a través de los países de América Latina.

    Ya se confirmaron dos oradores: Niko Matsakis del Rust Core Team y Boats de Rust Language Team para las charlas keynote. Pero está abierto el llamado a charlas. Hay 7 espacios disponibles para charlas de hasta 35 minutos. La organización de la conferencia cubre gastos de viaje (vuelos + hotel) por hasta USD 1.300, pero también aceptan que una compañía cubra los costos como espónsor bronce, y hay más opciones según cada caso.

    Las entradas “supporter” cuestan USD 100, un tipo de entrada para ayudar a que la conferencia se lleve a cabo de la mejor manera posible. Pero también van a haber entradas regulares a USD 50.

    Pueden visitar el sitio web por más información, comprar su entrada, o seguir a la conferencia en Twitter para enterarse de las novedades.

     

    Poesía Binaria: Proyectos, programación, y vidas online y offline

    $
    0
    0

    Han pasado varios meses desde mi último post. Creo que ha sido la temporada más larga sin escribir nada en el blog. Además, teniendo algnos posts programados que se publicaron automáticamente. Han sido unos meses de reflexión, nuevos proyectos y acontecimientos en mi vida online y offline.

    Durante este tiempo, aunque no he estado muy activo en redes sociales (no tanto como antes), he contestado mensajes, comentarios, y tweets. He retomado antiguos proyectos y rescatado ideas que tenía en mi cabeza hace más de diez años. Esos diez años que va a cumplir este blog en unos meses. ¡Que se dice pronto! Cerca de 700 posts en los que he aprendido mucho, porque siempre que se intenta explicar algo, se descubre nueva información, se cambia el punto de vista y se miran las cosas con otros ojos. Y con los que he conocido muchas personas.

    Después de mucho tiempo con mono de escribir, y con muchos apuntes de temas que me gustaría tratar en este blog, creo que es hora de volver. Seguir compartiendo código, ideas y reflexiones sobre programación, tecnología y software libre. Y si no me sigues en Facebook, Twitter o Instagram, tengo preparado algo de contenido para ponerme a dar guerra por esas redes. Aunque Facebook no me tiene muy contento con sus últimos cambios en los que impide muchas acciones de publicación a través de API. De todas formas, seguiremos intentando automatizarlo.

    Vuelvo a las andadas

    Solo quería decir esto. Estad atentos al blog, habrá novedades muy pronto.

    Foto principal: unsplash-logoToa Heftiba

    The post Proyectos, programación, y vidas online y offline appeared first on Poesía Binaria.

    Picando Código: Lanzado ATuServicio Bogotá 🏥

    $
    0
    0

    El viernes 16 de noviembre de 2018 se lanzó ATuServicio Bogotá. Se trata de una replicación independiente e innovadora del proyecto que originalmente desarrolláramos con DATA y el Ministerio de Salud de Uruguay.

    ATuServicio Bogotá

    Si ya conocen ATuServicio, verán que la estética es bastante similar, pero no deja de tener un toque personalizado. El sitio cuenta con un mapa de servicios, donde los usuarios pueden explorar los 300 centros de salud principales de Bogotá, reportar su experiencia y ayudar a mejorar la calidad de los servicios en la ciudad. Y por supuesto, los datos están disponibles como Datos Abiertos.

    Es genial ver que los proyectos de DATA sigan creciendo. Hemos hablado muchas ideas para ATuServicio, y con suerte para el año que viene podamos implementar varias y colaborar con más lugares. De la página:

    A tu Servicio Bogotá es una iniciativa de innovación cívica que se fundamenta en alianzas público-privadas duraderas y de sociedad civil que permitan superar las barreras institucionales y de confianza que disminuyen la efectividad de la interacción entre ciudadanos y el gobierno.

    La plataforma permite a los ciudadanos conocer y calificar la calidad, oportunidad y atención de los servicios que reciben en las Instituciones Prestadoras de Salud (IPS), públicas y privadas, que están habilitadas para funcionar en Bogotá.

    Los aportes ciudadanos se convierten en insumos directos con los cuales la Secretaría Distrital de Salud generará cambios en las políticas, programas y/o medidas con el fin de mejorar la atención en el servicio de salud.

    Esta plataforma surge de A Tu Servicio Uruguay, una buena práctica desarrollada en 2015 por Data Uruguay y Fundación Avina en alianza con el Ministerio de Salud de ese país. Anualmente los usuarios tienen la posibilidad de cambiar de asegurador, por esta razón, la plataforma cualifica la percepción ciudadana sobre el sistema para que su decisión esté intermediada por información de calidad.

    A Tu Servicio Bogotá incorpora los aprendizajes de Uruguay y los adapta a las necesidades del contexto colombiano partiendo de los avances que tiene el Observatorio de la Secretaría Distrital de Salud en datos abiertos e incorporando la experiencia del programa Así Vamos en Salud, Fundación Corona, la Plataforma de Innovación con Sentido, Fundación AVINA, CAF y Wingu en el desarrollo de tecnologías cívicas para involucrar a la ciudadanía en la toma de decisiones públicas y de veeduría ciudadana.

    La plataforma cuenta con las siguientes funcionalidades:

    • Mecanismo de reporte ciudadano y calificación de los servicios de salud con énfasis en la calidad de la atención en salud.
    • Retroalimentación y rendición de cuentas hacia la ciudadanía sobre las políticas, programas, medidas o ajustes implementados para mejorar la atención en el servicio de salud.
    • Información georreferenciada en datos abiertos de las principales 300 IPS de la ciudad. Estas IPS se priorizaron teniendo en cuenta la base de datos de SISPRO – BDUA del Ministerio de Salud y Protección Social; donde se tomaron las IPS con mayor número de atenciones para el año 2017 y a su vez las IPS acreditadas por INCOTEC.

    Visita ATuServicio Bogotá


    Poesía Binaria: Contenedores docker de aplicaciones de escritorio [con ejemplos listos para usar]

    $
    0
    0

    En los últimos años, han surgido varias tecnologías para compartimentar aplicaciones. Desde ejecutar una aplicación desde una jaula, hasta virtualizar un sistema operativo completo dentro de nuestro sistema. Algo que se utiliza mucho en servidores. Actualmente hay una tecnología en auge, y es Docker. Docker nos permite encerrar una aplicación, junto con las bibliotecas que necesita para funcionar y ejecutarla en un entorno aislado, de forma que la aplicación compartimentada no pueda ver nada del exterior. Aunque, si lo deseamos, podrá conectar por red con otros recursos o a Internet.

    Docker se usa mucho en el ámbito de los servidores. Nos permite ejecutar aplicaciones de manera que cada una se ejecute en un espacio determinado, con unos permisos, utilizando unos recursos de sistema definidos y utilizando un sistema operativo y bibliotecas de sistema determinadas, que pueden no ser las de nuestro sistema. Otra ventaja añadida es que los contenedores docker tienen un guión definido para su construcción, lo que nos asegura que la configuración del software del contenedor no variará entre instancias, podemos perfectamente configurarlo en nuestro ordenador local e instalarlo más tarde en un servidor cuando nos aseguremos de que todo esté bien, o hacer que todo un equipo (o empresa) utilice el mismo software, en la misma versión y con la misma configuración y evitar así la típica excusa de: “En mi ordenador funciona.”

    Docker en el escritorio

    Pero docker compartimenta aplicaciones, da igual del tipo que sean. Así que, ¿por qué no compartimentar aplicaciones de escritorio? De forma que encerremos todo lo que necesitamos de la misma en un entorno controlado y así evitamos tener problemas con dependencias, versiones, incluso con entornos Java cuando utilicemos dicha aplicación. Es muy común que una aplicación se actualice para utilizar bibliotecas en versiones muy nuevas y nuestra distribución no instale esas dependencias, incluso cuando las instalamos a mano, podemos meter la pata y hacer que nuestro sistema se vuelva inestable o que no funcione directamente. También es muy útil cuando necesitamos software que ya no está soportado, o necesitamos una versión antigua y vamos a ejecutarla en un sistema operativo más moderno que no instala las versiones de las bibliotecas que necesitamos.

    Puede parecer un gasto innecesario de disco duro, porque seguramente tengamos muchas bibliotecas y software repetido en nuestro sistema; y de memoria, porque habrá veces que la misma biblioteca esté cargada en RAM varias veces (aunque podemos optimizar un poco nuestro kernel para que no tenga mucho problema con eso). Pero nos dará seguridad en nuestro sistema, ya que esta aplicación estará aislada y no tendrá acceso a recursos sin permiso, para esa aplicación ni existirán. Y además, la posibilidad de llevarnos la aplicación a otro equipo o servidor, construirla allí y que todo esté igual que en nuestro ordenador.

    Construyendo el Dockerfile. Como ejemplo dbeaver

    Cada Dockerfile será independiente de la aplicación que necesitemos ejecutar. Aunque podemos utilizar este archivo como base. En este caso, vamos a dockerizar el programa dbeaver, una poderosa herramienta de administración de base de datos con muchas opciones. Como vemos, es una aplicación hecha en Java. Y, puede que en nuestro ordenador o nuestro servidor, no nos interese tener un entorno de Java públicamente disponible, y solo dejarlo para este programa.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    FROM ubuntu:18.04
    MAINTAINER Gaspar Fernandez <gaspar.fernandez@totaki.com>
    ARG UNAME=user
    ARG UID=1000
    ARG GID=1000

    RUN apt-get update \
            && apt-get -y install wget \
            && apt-get -y install libxext6 libxrender1 libxtst6 libxi6 software-properties-common \
            && apt-get -y install openjdk-8-jre \
            && wget -q --output-document=/tmp/dbeaver.deb https://dbeaver.io/files/dbeaver-ce_latest_amd64.deb \
            && dpkg -i /tmp/dbeaver.deb \
            && mkdir -p /home/$UNAME \
            && echo "$UNAME:x:${UID}:${GID}:Developer,,,:/home/$UNAME:/bin/bash">> /etc/passwd \
            && echo "$UNAME:x:${UID}:">> /etc/group \
            && chown ${UID}:${GID} -R /home/$UNAME \
            && gpasswd -a $UNAME audio \
            && gpasswd -a $UNAME video

    COPY docker-entry.sh /usr/local/bin
    ENTRYPOINT ["/usr/local/bin/docker-entry.sh"]

    USER $UNAME
    ENV HOME /home/$UNAME

    En este caso, partimos de una versión 18.04 de Debian, en la que tenemos que instalar dependencias del escritorio X y OpenDJK, seguidamente, descargar el .deb de la página oficial de dbeaver para proceder a la instalación del programa.
    Seguidamente, aunque podemos continuar como root, sobre todo para los programas de escritorio, no es aconsejable y muchos de ellos se quejan al arrancar. Así que creamos un usuario (podríamos cambiarle el nombre al usuario, aunque no será tan importante, por ahora se llamará user). Luego le asignamos grupos (en este caso no es tan importante, pero hay programas con los que sí).

    Generalmente, me gusta escribir un docker-entry.sh para cada aplicación a dockerizar, aunque solo sea para ejecutar el programa nada más. Porque, a veces tenemos que filtrar argumentos, ejecutar un pequeño script antes que el programa o hacer una copia de la configuración, etc. En este caso, nuestro docker-entry.sh será este:

    1
    2
    3
    4
    #!/bin/bash

    echo"Ejecutando dbeaver..."
    dbeaver

    Tras ello, aunque podríamos utilizar docker-compose, vamos a crear un script para construir el contenedor y otro para ejecutar la aplicación. Aunque la ejecución es más o menos sencilla, no tenemos por qué recordar los argumentos para ejecutar el programa. Además, así podremos crear más fácilmente accesos directos y otras utilidades derivadas.

    build.sh

    1
    2
    3
    4
    5
    6
    #!/bin/bash
    readonlySCRIPTPATH="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"

    pushd $SCRIPTPATH
    docker build -t gasparfm/dbeaver .
    popd

    Primero, almacenamos en la variable SCRIPTPATH el nombre del directorio donde se encuentra el script, me gusta utilizar esta línea por si llamamos al script desde una ruta diferente a la ruta donde está, o si hacemos un enlace simbólico al archivo. De esta forma, obtendremos en la variable la ruta exacta donde se encuentra el archivo de script al que hace referencia el enlace. Y así podremos realizar tareas en ese directorio, como por ejemplo la construcción de la imagen de nuestro contenedor.

    run.sh

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #!/bin/bash
    readonlySCRIPTPATH="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"

    pushd $SCRIPTPATH
    docker run --rm --name dbeaver -e DISPLAY=$DISPLAY\
        -v /dev/shm:/dev/shm:rw \
        -v /etc/machine-id:/etc/machine-id:ro \
        -v /var/lib/dbus:/var/lib/dbus:ro \
        -v /tmp/.X11-unix:/tmp/.X11-unix \
        -v /etc/localtime:/etc/localtime:ro \
        -v /etc/hosts:/etc/hosts:ro \
        -v $(pwd)/user:/home/user \
        -v $HOME/.ssh:/home/user/sshkeys:ro \
        gasparfm/dbeaver
    popd

    Para ejecutar el script, podemos crear un enlace en /usr/local/bin a este archivo, llamándolo como queramos. Aquí comento algunos argumentos utilizados:

    • –rm: Borra el contenedor si existe. Para utilizar siempre el mismo, porque normalmente solo vamos a necesitar una instancia en ejecución
    • –name dbeaver: Le damos nombre al contenedor, para que no tenga un nombre aleatorio.
    • -e DISPLAY=$DISPLAY: Asignamos la pantalla sobre la que escribirá la aplicación a la pantalla actual del usuario.
    • -v /dev/shm:/dev/shm:rw: Algunos programas necesitan acceso a este dispositivo de memoria compartida.
    • -v /etc/machine-id:/etc/machine-id:ro : Extraemos el identificador único de la máquina.
    • -v /var/lib/dbus:/var/lib/dbus:ro : En este directorio también suele almacenarse el identificador único de la máquina.
    • -v /tmp/.X11-unix:/tmp/.X11-unix : En este directorio suelen almacenarse los sockets para acceder al entorno X.
    • -v /etc/localtime:/etc/localtime:ro : Aquí reside la zona horaria de nuestro ordenador y la vinculamos con la de la aplicación dockerizada.
    • -v /etc/hosts:/etc/hosts:ro : Si tenemos hosts personalizados en /etc/hosts, nuestra aplicación debe poder acceder a ellos. O, al menos, resolverlos.
    • -v $(pwd)/user:/home/user : Vinculamos el directorio local user (tendremos que crearlo) con el /home/user de la aplicación. Sobre todo porque este programa introduce mucha información que debe ser salvada. Por ejemplo, se descarga drivers de base de datos o genera muchos archivos de configuración, etc.
    • -v $HOME/.ssh:/home/user/sshkeys:ro : Una opción de este programa es que nos permite acceder a bases de datos a través de túneles SSH. Por eso mismo, estaría bien poder acceder a nuestras claves privadas de SSH. Podríamos montar este volumen así o copiar las claves a mano al directorio user.
    • gasparfm/dbeaver : Es el nombre del contenedor

    Solo tendremos que ejecutar el programa:

    Dockerizando yed

    Ahora vamos a incluir un segundo programa, yed. Un software para crear diagramas, hecho en Java también. Pero esta vez necesita del JRE de Oracle. Lo que ya nos da una pista de la potencia y necesidad de dockerizar este tipo de aplicaciones.

    Vamos a seguir el mismo sistema, creamos Dockerfile, docker-entry.sh, build.sh y run.sh.

    Dockerfile

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    FROM ubuntu:18.04
    MAINTAINER Gaspar Fernandez <gaspar.fernandez@totaki.com>
    ARG VERSION=3.18.1.1
    ARG UNAME=user
    ARG UID=1000
    ARG GID=1000

    RUN apt-get update \
            && apt-get -y install wget \
            && apt-get -y install libxext6 libxrender1 libxtst6 libxi6 software-properties-common unzip
    RUN add-apt-repository ppa:webupd8team/java \
            && apt-get update \
            && echo debconf shared/accepted-oracle-license-v1-1 select true | \
                    debconf-set-selections \
            && echo debconf shared/accepted-oracle-license-v1-1 seen true | \
                    debconf-set-selections \
            && apt-get -y install oracle-java8-installer
    RUN wget -q --output-document=/tmp/yEd.zip https://www.yworks.com/resources/yed/demo/yEd-${VERSION}.zip \
            && unzip /tmp/yEd.zip -d /opt/ \
            && mkdir -p /home/$UNAME \
            && echo "$UNAME:x:${UID}:${GID}:Developer,,,:/home/$UNAME:/bin/bash">> /etc/passwd \
            && echo "$UNAME:x:${UID}:">> /etc/group \
            && chown ${UID}:${GID} -R /home/$UNAME \
            && gpasswd -a $UNAME audio \
            && gpasswd -a $UNAME video

    COPY docker-entry.sh /usr/local/bin
    ENTRYPOINT ["/usr/local/bin/docker-entry.sh"]

    USER $UNAME
    ENV HOME /home/$UNAME

    docker-entry.sh:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/bin/bash

    ARGS=''
    if[$#-ge1]; then
      ARGS="$HOME/$(basename $1)"
      shift1
      ARGS="$@ $ARGS"
    fi

    java-jar"/opt/$(ls)/yed.jar"$ARGS

    Esta vez, necesitamos que yed acepte argumentos del usuario, como por ejemplo el archivo que vamos a abrir.

    build.sh

    1
    2
    3
    4
    5
    6
    7
    #!/bin/bash

    readonlySCRIPTPATH="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"

    pushd $SCRIPTPATH
    docker build -t gasparfm/yed .
    popd

    run.sh

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #!/bin/bash
    readonlySCRIPTPATH="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"

    pushd $SCRIPTPATH
    docker run --rm --name yed -e DISPLAY=$DISPLAY\
        -v /dev/shm:/dev/shm:rw \
        -v /etc/machine-id:/etc/machine-id:ro \
        -v /var/lib/dbus:/var/lib/dbus:ro \
        -v /tmp/.X11-unix:/tmp/.X11-unix \
        -v /etc/localtime:/etc/localtime:ro \
        -v /etc/hosts:/etc/hosts:ro \
        -v $(pwd)/user:/home/user \
        gasparfm/yed
    popd

    Otras ideas: navegadores

    De la misma forma podemos construir programas libres o privativos. Introduciendo una capa de seguridad en estos últimos, ya que no tendremos forma de saber lo que hacen. Incluso instalando versiones determinadas de wine para hacer funcionar algunos programas. Y como última idea, podemos dockerizar navegadores, instalaciones completas de Firefox / Chrome / Chromium en las que podremos limitar los recursos para no engullir RAM o CPU (podríamos limitarles la memoria a 1Gb, por ejemplo).

    Dockerfile

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    FROM ubuntu:18.04
    ARG UNAME=user
    ARG UID=1000
    ARG GID=1000

    RUN apt-get update \
        && apt-get -y install sudo iproute2 \
        && apt-get -y install chromium-browser \
        && apt-get -y clean
    RUN mkdir -p /home/$UNAME && \
        echo "$UNAME:x:${UID}:${GID}:Developer,,,:/home/$UNAME:/bin/bash">> /etc/passwd && \
        echo "$UNAME:x:${UID}:">> /etc/group && \
        chown ${UID}:${GID} -R /home/$UNAME \
        && gpasswd -a $UNAME audio \
        && gpasswd -a $UNAME video \
        && echo "$UNAME ALL=(ALL:ALL) NOPASSWD: ALL"> /etc/sudoers.d/user

    COPY docker-entry.sh /usr/local/bin
    RUN chmod +x /usr/local/bin/docker-entry.sh
    USER $UNAME
    ENV HOME /home/$UNAME

    ENTRYPOINT ["/usr/local/bin/docker-entry.sh"]

    docker-entry.sh:

    1
    2
    3
    4
    #!/bin/bash

    # Podríamos incluir argumentos aquí.
    chromium-browser

    build.sh:

    1
    2
    3
    4
    5
    6
    #!/bin/bash
    readonlySCRIPTPATH="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"

    pushd $SCRIPTPATH
    docker build --build-arg UID=$(id -u) --build-arg GID=$(id -g) --build-arg UNAME=user -t gasparfm/chromium .
    popd

    run.sh:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #!/bin/bash

    readonlySCRIPTPATH="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"

    pushd $SCRIPTPATH

    docker run -i --rm --name chromium --privileged -e DISPLAY=$DISPLAY\
        -v /dev/shm:/dev/shm:rw \
        -v /etc/machine-id:/etc/machine-id:ro \
        -v /run/user/$UID/pulse:/run/user/$UID/pulse:rw \
        -v /var/lib/dbus:/var/lib/dbus:ro \
        -v /tmp/.X11-unix:/tmp/.X11-unix \
        -v $(pwd)/user:/home/user \
        --device /dev/video0 \
        --memory="
    1000m"\
        --cpus 1 \
        gasparfm/chromium
    popd

    En este caso, lo estamos limitando su procesamiento a 1 CPU (o núcleo) y aproximadamente 1Gb de memoria.

    Aplicaciones dockerizadas

    Y tú, ¿qué aplicación de escritorio dockerizarías?

    Foto principal: unsplash-logoandrew jay

    The post Contenedores docker de aplicaciones de escritorio [con ejemplos listos para usar] appeared first on Poesía Binaria.

    Blog Bitix: Flatpak, distribución e instalación de programas de escritorio en las distribuciones GNU/Linux

    $
    0
    0
    Flatpak
    Linux

    Las distribuciones GNU/Linux son la recolección de cantidad de programas de software libre, cientos o miles, con una garantía de que funcionan correctamente en esa distribución y que facilita a los usuarios una fácil utilización. Hay múltiples distribuciones GNU/Linux con diferentes intereses ya sean generalistas como Ubuntu, Fedora, Debian, Arch Linux, elementary, openSUSE entre las más populares y otras especializadas en propósitos más específicos para servidor con RHEL, CentOS, Zentyal o Alpine, para equipos con pocos recursos como Puppy o Tiny Core, seguridad y privacidad como Tails o sin componentes privativos como Trisquel.

    Cada una de estas distribuciones es creada por personas que se encargan de mantener la distribución cogiendo el código fuente que los programadores del software crean y publican, compilandolo para crear un binario o paquete utilizable e instalable en esa distribución y comprobar que funciona correctamente sin conflictos con otros paquetes. Los mantenedores se encargan de publicar nuevas versiones de paquetes con cada nueva versión de cada programas, de reportar errores y de incluso aplicar parches de seguridad cuando se descubren.

    Esta tarea que hacen los mantenedores se hace por cada paquete, son miles los que contiene una distribución, Debian tiene más de 51000, y por cada distribución aunque algunas se basan en otras como Ubuntu se basa en Debian y otras se basan a su vez en Ubuntu. Esto es una ingente cantidad de tiempo de dedicación de muchas personas y replicado en gran parte en cada distribución que podrían ser empleado en otras tareas.

    La tarea que hacen los mantenedores es útil para comprobar que los paquetes de cada distribución funcionan correctamente y en conjunto con el resto de paquetes y porque los autores originales del software no tenían una forma de distribuir su software para que funcionase correctamente en todas las distribuciones.

    Flatpak se define como el futuro, aunque es ya un presente, de forma de distribuir aplicaciones de escritorio siendo varias distribuciones GNU/Linux importantes que ya lo soportan. Las ventajas que proporciona son:

    • Los paquetes de flatpak son utilizables en cualquier distribución.
    • Los autores del software pueden crear el paquete sin depender de que los mantenedores lo incluyan en una distribución para que sea utilizable por sus usuarios.
    • Una nueva versión está disponible inmediatamente para todas las distribuciones que será más una buena mejora para distribuciones con ciclos de publicación más lentos.
    • Proporciona entornos consistentes.
    • Las aplicaciones son utilizables incluso en nuevas versiones de una distribución.
    • Se pueden instalar múltiples versiones de una misma aplicación.
    • Hay menos riesgo de que una actualización de un programa provque que el sistema quede inconsistente pudiendo incluso a no llegar a iniciarse correctamente.
    • Se mejora la seguridad el ejecutarse las aplicaciones de forma aislada en una caja de arena que limita las acciones que puede realizar. Los permisos como almacenamiento, red y dispositivos se han de conceder de forma explícita.
    • Cualquiera puede publicar su aplicación y ser utilizable por los usuarios sin que necesite ganar popularidad para que los mantenedores la incluyan en la distribución.
    • Las aplicaciones Flatpak se puede instalar a nivel de sistema (por defecto) y a nivel de usuario.

    La instalación de Flatpak y guía de uso no es más complicado que utilizar el propio gestor de paquetes de cada distribución. Los desarrolladores tienen su guía para crear paquetes y publicar en Flatpak.

    Flathub es un repositorio de las aplicaciones Flatpak que en el ejemplo se añade con el comando con flatpak remote-add. Las que hay se pueden navegar por categoría y son algunas de las más populares y que es probable querer instalar en cualquier sistema. A medida que pase el tiempo habrá más disponibles.

    • Audio y vídeo: Audacity, GNOME Music, HandBrake, OpenShot, Pitivi, Rhythmbox, VLC, …
    • Desarrollo: Atom, gitg, Meld, Backets, Sequeler, SmartGit, Sublime Text, Visual Studio Code, …
    • Educación: GCompris, GeoGebra, GNU Octave, …
    • Juegos: 0 A.D, Battle for Wesnoth, Games, gbrainy, GNOME Chess, OpenTTD, ScummVM, Shattered Pixel Dungeon, Steam, SuperTuxKart, Teeworlds, …
    • Gráficos y fotografía: Blender, Colo , GNU Image Manipulation Program (GIMP), Image Optimizer, Inkscape, Krita, Scribus, Synfig Studio, …
    • Comunicación y noticias: Dropbox, FeedReader, FileZilla, Geary, JDownloader, Pidgin, Polari, Remmina, Signal, Skype, Slack, Telegram, Thunderbird, Transmission, …
    • Productividad: Calendar, Calibre, Contacts, Evolution, LibreOffice, Thunderbird, …
    • Ciencia: Elements, Genius, Stellarium, …
    • Configuración: RazerGenie, …
    • Utilidades: Agenda, FreeFileSync, KeePassXC, Nextcloud, Vim, …

    Con las ventajas de Flatpak tanto para usuarios, desarrolladores y mantenedores y a medida que gane más popularidad los desarrolladores tendrán más motivación por publicar sus aplicaciones en paquete Flatpak y en alguno de sus repositorios.

    En la página de preguntas frecuentes está el curioso origen del nombre de Flatpak en relación con una de las innovaciones de paquetes planos de IKEA. Es una tecnología acoplada a Linux ya que utiliza varias de las tecnologías propias de Linux y por tanto no está para las distribuciones BSD como ocurre en otros casos. El entorno de desarrollo GNOME Builder soporta la programación para Flatpak.

    Flatpak está más apoyada por Red Hat, Canonical tiene su tecnología similar con snaps. Ha ocurrido igual en anteriores casos con systemd y Upstart o Wayland y Mir donde las tecnologías más apoyadas por Red Hat han sido las que mayor éxito han tenido y han prevalecido. Si nada cambia en Red Hat al ser adquirida por parte de IBM puede que se produzca el mismo resultado no tanto por que las tecnologías de Red Hat sean mejores sino porque tiene más peso en la comunidad que Canonical. Por el momento la adopción para snap contra la de Flatpak no produce buenos augurios para la primera donde solo en Ubuntu es buena como no podría ser de otra forma.

    Si usas Arch Linux e instalas el entorno de escritorio GNOME con los paquetes gnome y gnome-extra ya tendrás instalado Flatpak ya que se instala como dependencia. Se puede instalar directamente con el gestor de paquetes pacman con el siguiente comando:

    Variable not found: Enlaces interesantes 339

    $
    0
    0
    Enlaces interesantesAhí van los enlaces recopilados durante la semana pasada, algo más escasa de lo habitual debido a los festivos en USA. Pocos, pero espero que interesantes :-)

    Por si te lo perdiste...

    .NET / .NET Core

    ASP.NET / ASP.NET Core

    Azure / Cloud

    Conceptos / Patrones / Buenas prácticas

    Web / HTML / CSS / Javascript

    Visual Studio / Complementos / Herramientas

    Xamarin

    Otros


    Publicado en: www.variablenotfound.com.

    Poesía Binaria: Cómo hacer carpetas IMAP compartidas con Cyrus

    $
    0
    0

    Un servicio de correo electrónico suele ser algo personal. Sin embargo hay ocasiones en las que nos interesa que varios usuarios sean capaces de gestionar conjuntamente un buzón de correo. Podemos pensar el caso de una empresa en la que varios empleados reciben los mensajes de una dirección de correo determinada, por ejemplo info@miembpresa.com, y que de vez en cuando el jefe viene a echar un vistazo a dichos correos. O que, por ejemplo tenemos que enviar decenas o cientos de mensajes a otro usuario dentro del mismo servidor, podemos pensar en que un empleado deja la empresa y otro compañero va a encargarse de las conversaciones que tenga actualmente con los clientes.

    Es cierto que, en la práctica, muchas veces se opta por compartir las contraseñas del correo y configurar todo el mundo la misma cuenta en su programa de correo, y ahí hacer los cambios que creamos oportunos. Aunque, si queremos tener en cuenta la seguridad, una cuenta como info@miempresa.com no puede tener su contraseña volando por la oficina. En primer lugar, no sabemos si un empleado filtrará la clave o utilizará la cuenta para fines diferentes a los que pensamos. Y, si confiamos en nuestros empleados, no podemos confiar en sus ordenadores que en cualquier momento puede tener algún problema, ser víctimas de malware y pueden jugarnos una mala pasada. Si hay una filtración, no podríamos determinar con exactitud su procedencia. Por otro lado, no podríamos limitar el acceso a dicha cuenta si nos interesa que un usuario solo pueda leer los mensajes o no queremos que pueda marcar mensajes como leídos (muy útil cuando el jefe quiere supervisar mensajes sin entorpecer).

    En mis servidores utilizo el software Cyrus para gestionar el correo entrante en el servidor. Con él manejo las cuentas IMAP de los usuarios y todos ellos se conectan a él para la lectura de su correo. Es aquí donde podemos hacer uso de las capacidades de buzones de correo compartidos para satisfacer nuestras necesidades.

    Notas iniciales

    Estas configuraciones son válidas tanto para Cyrus 2.2 como Cyrus 2.4 (lo he probado en las dos versiones). Además, yo estoy utilizando la directiva

    1
    unixhierarchysep: yes

    en el archivo /etc/imapd.conf que habilita puntos (.) en los nombres de usuario, con lo que la separación de niveles en lugar de un punto utilizará una /. De todas formas comentaré esto donde sea necesario.

    Otra cosa más, en los nombres de usuario y los buzones, a mí me gusta poner siempre el dominio al que pertenecen, aunque es incómodo de escribir siempre, me sirve como una medida de seguridad ante confusiones y me permite crear buzones en dominios diferentes, que cuando te piden un correo en un dominio temporalmente, o el dominio tiene alternativas en .es, .eu o .com es un engorro ponerlo todo bien con su dominio.

    Dando de alta el buzón compartido

    Para ello, tenemos que identificarnos en la administración de cyrus. En mi caso, el usuario es administrador y el host es localhost porque estoy en el mismo servidor de correo:

    cyradm -u administrador localhost

    Luego, tendremos que crear el buzón compartido, en mi caso (info@miempresa.com):

    cm shared/info@miempresa.com

    ¡Cuidado! Si no tienes unixhierarchysep: yes, tendrás que utilizar un punto en lugar de una barra (compruébalo antes de hacer cambios):
    cm shared.info@miempresa.com

    Dando permisos al buzón

    Tras ello, tenemos que dar permisos, imaginemos que tenemos dos empleados, ana@miempresa.com y bruno@miempresa.com , y por si fuera poco, tenemos a jefe@miempresa.com que quiere poder ver mensajes, pero que no se note su presencia. Cyrus establece las siguientes flags de permisos (y cuando las usas un par de veces, te las puedes aprender en este orden lrswipcda):

    • l: (lookup) Nos permite obtener este buzón en un listado.
    • r: (read) Da permiso de lectura a los contenidos del buzón.
    • s: (seen) Mantiene el estado de seen/recent entre varias sesiones IMAP. Los mensajes vistos y recibidos recientemente.
    • w: (write) Escritura de flags en los mensajes del buzón.
    • i: (insert) Permite copiar o mover mensajes aquí.
    • p: (post) Nos deja entregar un mensaje en este buzón.
    • c: (create) Crear un nuevo sub-buzón.
    • d: (delete) Nos deja borrar mensajes o el propio buzón.
    • a: (acl) Nos deja administrar el buzón, o cambiar estos permisos del ACL.

    Así que, para dar permiso a los usuarios seleccionados, y adicionalmente dejar que cualquiera pueda entregar correos aquí:

    sam shared/info@miempresa.com info@miempresa.com anyone p
    sam shared/info@miempresa.com ana@miempresa.com lrswipcda
    sam shared/info@miempresa.com bruno@miempresa.com lrswipcda
    sam shared/info@miempresa.com jefe@miempresa.com lr

    Podríamos utilizar setaclmailbox en lugar de sam. En este punto, ya podríamos utilizar el buzón desde los usuarios ana, bruno y jefe.

    Recibir correo en el buzón compartido desde Postfix

    Si queremos habilitar la entrega de correo a través de una dirección de e-mail, primero debemos establecer un usuario que se utilizará para hacer la entrega. Para ello, editamos /etc/imapd.conf de la siguiente forma (el nombre de usuario puede ser el que queramos, siempre y cuando no esté en el sistema):

    1
    postuser: sharedmanager

    Podemos colocar dicha línea en cualquier punto del archivo, yo prefiero poner al final todas las modificaciones a ese archivo.

    Ahora, debemos crear un alias de correo a un nombre de usuario del sistema. Para ello editamos /etc/postfix/valias introduciendo lo siguiente:

    1
    info@miempresa.com infomiempresacom

    Así le decimos que info@miempresa.com corresponde con el alias infomiempresacom, que introduciremos en /etc/aliases así:

    1
    infomiempresacom: sharedmanager+shared/info@miempresa.com

    Tras esto, dependiendo de la configuración que tengamos en postfix (el contenido debe venir precedido por “hash:” virtual_alias_maps y alias_maps en /etc/postfix/main.cf ; Nota, mis archivos se llaman /etc/aliases y /etc/postfix/valias, los tuyos tal vez sean distintos), tendremos que ejecutar lo siguiente:

    sudo postalias /etc/aliases
    sudo postmap /etc/postfix/valias

    Con esto crearemos los archivos /etc/aliases.db y /etc/postfix/valias.db. Ya deberíamos poder recibir los e-mails enviados a info@miempresa.com en el buzón compartido por Ana y Bruno. Cada usuario utilizará su contraseña para entrar en el buzón y el jefe podrá leer todos los mails sin marcarlos como leídos, ni quitar el flag de recién recibido.

    Foto principal: unsplash-logoAnnie Spratt

    The post Cómo hacer carpetas IMAP compartidas con Cyrus appeared first on Poesía Binaria.

    Variable not found: Mi controlador tiene muchos parámetros en el constructor, ¿estoy haciendo algo mal?

    $
    0
    0
    DesarrolladoresComo sabemos, la inyección de dependencias está grabada a fuego en los genes de ASP.NET Core. La mayoría de sus componentes la usan internamente para obtener acceso a otros componentes que necesitan para cumplir sus funciones y, además, es una práctica recomendada en la parte que nos toca a nosotros como desarrolladores de aplicaciones.

    Por ello, en ASP.NET Core MVC, lo habitual es que implementemos nuestros controladores atendiendo a este principio, y para ello utilicemos la técnica de inyección de dependencias en el constructor:
    public class InvoiceController: Controller
    {
    private readonly IInvoiceServices _invoiceServices;
    private readonly IMapper _mapper;
    private readonly ILogger<InvoiceController> _logger;

    public InvoiceController(
    IInvoiceServices invoiceServices,
    ILogger<InvoiceController> logger,
    IMapper mapper)
    {
    _invoiceServices = invoiceServices;
    _logger = logger;
    _mapper = mapper;
    }
    ...
    }
    Nota: aunque en este post estemos hablando de controladores ASP.NET Core MVC, las ideas que vamos a comentar aquí son también aplicables a ASP.NET MVC "clásico" e incluso a otro tipo de frameworks que comparten los mismos conceptos.

    Controladores endiosados, o dioses controladores

    Cuando el controlador crece, es probable que la lista de parámetros del constructor también aumente de forma significativa, lo cual se convierte automáticamente en un code smell (¡hola, "S" de SOLID!). Llegado este caso, probablemente estemos otorgando demasiadas responsabilidades a este controlador, y, con ello, disminuyendo su cohesión, legibilidad, mantenibilidad y robustez.

    De la misma forma, podemos encontrarnos con un exceso de responsabilidades, pero no sólo desde el punto de vista numérico, sino conceptual. A veces trasladamos al controlador responsabilidades que serían más propias del modelo, y esto se refleja claramente en las dependencias que declaramos en su constructor.

    Por último, también hay que pensar que no todas las acciones del controlador utilizarán todas las dependencias recibidas. Por tanto, en determinadas ocasiones estaremos instanciando un grafo de objetos excesivo para el uso real que vamos a darle en el proceso de una petición, lo cual puede tener su repercusión en términos de rendimiento y memoria, sobre todo si la estructura de dependencias es compleja. Esto podría ser especialmente doloroso si alguna de las dependencias tiene un constructor complejo o que realice tareas costosas (algo que, por otra parte, no es recomendable en absoluto), porque estaríamos sometiendo al sistema a un stress innecesario cuando la acción a ejecutar no requiera dicha dependencia para llevar a cabo su misión.

    La cuestión es que, con el paso del tiempo, si no tenemos cuidado podríamos llegar a tener un controlador con aspiraciones divinas como el siguiente:
    public class InvoiceController: Controller
    {
    private readonly IInvoiceServices _invoiceServices;
    [...] // Other private members

    public InvoiceController(
    IInvoiceServices invoiceServices,
    ICustomerServices customerServices,
    ISupplierServices supplierServices,
    IStockServices stockServices,
    IDeliveryServices deliveryServices,
    IDigitalSignatureServices digitalSignatureServices,
    IAuthorizationServices authorizationServices,
    IAuditServices auditServices,
    IMailingService mailingServices,
    ISmsServices smsServices,
    IPushServices pushServices,
    IPdfGenerator pdfGenerator,
    IMapper mapper,
    ILogger<InvoiceController> logger,
    [...]
    )
    {
    _invoiceServices = invoiceServices;
    _customerServices = customerServices;
    _supplierServices = supplierServices;
    _stockServices = stockServices;
    _deliveryServices = deliveryServices;
    _digitalSignatureServices = digitalSignatureServices;
    _authorizationServices = authorizationServices;
    _auditServices = auditServices;
    _mailingServices = mailingServices;
    _smsServices = smsServices;
    _pushServices = pushServices;
    _pdfGenerator = pdfGenerator;
    _mapper = mapper;
    [...]
    }
    ...
    }

    Pues sí, así son mis controladores... ¿cómo lo soluciono?

    Si ya estamos en este punto, o incluso bastante antes, podemos asegurar que tenemos un problema. Lo mejor es empezar a actuar inmediatamente; cuanto más tardemos en empezar a refactorizar, más difícil será el proceso para dejarlo todo en condiciones.

    Esta refactorización podría ir enfocada a las siguientes líneas de actuación:
    • Trocear el controlador en controladores más especializados, pequeños y manejables. Por ejemplo, un controlador para gestionar todo lo relativo con facturación suena demasiado ostentoso, ¿verdad? Quizás deberíamos plantearnos tener controladores específicos para la generación de facturas, otros para reportes, otro para firmas electrónicas, etc. El resultado será un diseño respetuoso con el principio SRP y clases bastante más especializadas y con muchas menos dependencias.

    • Extraer funcionalidades trasversales a filtros. Por ejemplo, en el caso anterior serían buenos candidatos los servicios de autorización o auditoría. Esto nos ayudará a tener controladores mucho más pequeños y a reutilizar bastante código, pues en muchas ocasiones estas operaciones trasversales son comunes entre acciones e incluso entre distintos controladores.

    • Mover funcionalidades al Modelo. En el ejemplo anterior lo vemos claramente: si nuestra aplicación debe enviar una notificación cada vez que se crea una factura, el envío del mail no debería realizarlo el controlador, sino la clase del Modelo que proporciona los servicios de creación de las mismas, porque este proceso forma parte de la lógica de negocio del sistema. Confundir la ubicación de determinadas funciones es uno de los principales causantes de estos controladores subidos de peso.

    • Agrupar servicios en abstracciones de nivel superior. Por ejemplo, no tiene sentido que el controlador reciba dependencias a servicios de notificaciones por email, SMS o push; quizás deberíamos plantearnos tener un INotificationSender que sea el que decida por qué vía debe notificar al usuario y encapsule las dependencias que implementan cada tipo de mensaje. En muchas ocasiones, el uso de niveles de abstracción incorrectos hacen que nuestras clases tengan que recibir más dependencias de la cuenta y aumentar la cantidad de código implementado en las mismas.

    • No estaría de más echar un vistazo a patrones como Mediator, Facade, Command, y arquitecturas tipo CQS, uso de eventosu otras técnicas que nos ayuden a simplificar nuestros componentes y las relaciones entre ellos.
    En cualquier caso, salvo ocasiones muy justificadas, lo que no deberíamos hacer es ceder ante la tentación de intentar disimular el exceso de dependencias mediante la instanciación directa o el uso de service locators u otras técnicas de inyección. Aunque estas herramientas pueden resultar útiles en determinados escenarios, pueden dar lugar a problemas porque harán menos visibles las dependencias y, por tanto, menos evidentes la violación del principio de separación de responsabilidades, que al final es lo que tenemos que evitar.

    Pero... ¿cuántos parámetros son demasiados parámetros en el constructor?

    Pues no creo que haya un número exacto de parámetros que actúe como frontera entre lo correcto y lo incorrecto. Como suele ocurrir, depende de los escenarios: puede haber controladores en los que tres parámetros ya sean demasiado porque estemos introduciendo en él más responsabilidades de la cuenta, y puede haber otros donde recibir seis dependencias pueda resultar correcto porque sean esenciales para realizar las tareas que tenga encomendadas.

    Eso sí, parece existir un cierto consenso en que a partir de cuatro parámetros debemos activar las alertas y empezar a plantearnos si es necesario refactorizar, y el nivel de probabilidad de que sea necesaria dicha refactorización irá subiendo de forma exponencial conforme aumente el número de parámetros.

    Publicado en: www.variablenotfound.com.

    Una sinfonía en C#: Los memes de Javascript

    $
    0
    0

    No pasan más de 10 minutos desde que algo ocurre en el mundo hasta que Internet se llena de memes al respecto; sin embargo últimamente se ven muchos memes sobre Javascript y la idea de este post es explicarlos, o mejor dicho, explicar por qué son incorrectos.

    El meme en cuestión

    En meme del que voy a hablar en esta ocasión es éste, con Patrick Star de protagonista:

     

    image

     

    En este caso es una burla acerca de ciertos casos con las comparaciones en Javascript, y si bien tiene algo de gracia demuestra más que nada desconocimiento del lenguaje y vamos a explicarlo.

    El comparador de igualdad

    El comparador de igualdad de Javascript tiene una característica interesante que se podría resumir como que “hace el mejor esfuerzo por comparar los dos términos” para explicarlo simple: el comparador convierte los dos término en caso de no ser del mismo tipo y luego hace una comparación estricta, entonces esto nos lleva a la primera parte del meme:

    0 == “0”
    

    Básicamente al usar el comparador de igualdad ==Javascript detecta que los términos no son del mismo tipo y los convierte, entonces esta comparación pasa a ser verdad como podemos ver al probarlo en Nodejs

    image

    es por eso que si queremos una comparación estricta usamos el operador de comparación estricta ===

    image

    Entonces, primer caso resulto, Javascript hace exactamente lo que dice la documentación que debe hacer, una comparación con conversión de tipos.

    Un array vacío

    Los arrays siempre tienen sus bemoles en todos los lenguajes y Javascript no es la excepción, pero por qué  0 == [ ] ?

    La respuesta es que la conversión de un array vacío a entero nos retorna el valor de una posición de memoria vacía que es comparable con 0, entonces la comparación es verdadera, una vez más si usamos el comparador estricto es no es así:

    image

    La comparación con un string es false

     

    "0" == [] 

    Acá es simple, basados en lo anterior, es evidente que podemos convertir un array vacío a entero y nos retorna algo comprable con false porque después de todo estamos pidiendo que haga un esfuerzo por convertir una posición sin valores. En este caso el término de la derecha resultará ser o o algo comparable con false, sin embargo ahora el término de la izquierda es un string que a lo sumo es comparable con un 0.

    Conclusión

    Un lenguaje de programación es complejo y tiene detalles, si en el día a día lo usamos debemos conocer sus características y no olvidarnos que puede ser (como en el caso de Javascript) un lenguaje diseñado hace muchos años y si estamos acostumbrados a lenguajes más modernos que han aprendido de los problemas que pueden acarrear estas cosas y que los programadores de hoy en día usan un lenguaje sin conocerlo…

     

    Nos leemos.

    Blog Bitix: Desempaquetado Intel NUC8i5BEK (Bean Canyon), HyperX Impact (RAM) y Samsung 970 EVO NVMe (SSD)

    $
    0
    0

    Al fin tengo nuevo equipo que cumple con los requisitos que le demandaba. Principalmente que sea pequeño pero al mismo tiempo suficientemente potente para que me suponga un salto notable en rendimiento respecto al portátil que tenía. Después de decidirme entre nuevo portátil, ITX o NUC me decidí por unos de los nuevos Bean Canyon con procesador de 4 núcleos y 8 hilos, posibilidad de SSD con NVMe y hasta un máximo de 32 GiB de RAM.

    Intel
    HyperX
    Samsung

    Llevaba unos cuantos meses buscando entre las muchas opciones que hay un nuevo ordenador personal, casi un año desde enero del 2018 hasta ahora noviembre. La espera en algunos momentos se me ha hecho larga ya que sobre Intel NUC por el que me he decidido como nuevo equipo ya había noticias de él en enero, sin embargo, hasta julio no los empezaba a distribuir Intel y no ha sido hasta octubre y noviembre (coincidiendo con la semana del black friday a finales de noviembre) cuando ha empezado a estar disponible en las tiendas para comprar. Ha sido tanto tiempo por el conjunto de características que deseaba que limitaba en buena medida las opciones entre las que podía elegir, más cuando en las tiendas aún no estaba el equipo que quería. Por algunas cosas aún seguiría esperando pero ya me decidido a quedarme con el NUC ya que no quiero esperar más a tener mi propio equipo. Por obligación estoy usando un Apple MacBook Pro del 2015 que tengo a mi disposición por motivos laborales pero echo de menos mi distribución GNU/Linux preferida que es Arch Linux.

    Anteriores equipos

    Siempre que puedo cuando algún familiar necesita un ordenador lo que hago es darle el que tengo yo y yo comprar uno nuevo, de esta forma al ordenador que entrego le doy una segunda vida para la que es perfectamente útil, así ha sido con los tres ordenadores que he comprado hasta el momento desde el 2002. Mis usos son mucho más exigentes, principalmente los equipos se me han quedado pequeños por la cantidad de memoria RAM. El primer ordenador que compré en el 2004 fue un ordenador de escritorio en formato torre tradicional ATX con un AMD Athlon 1800+ (32 bits), 512 MiB de memoria, 60 GB de disco duro y tarjeta gráfica NVIDIA GeForce2 MX 400 creo que con 32 MiB. Viendo que al finalizar su vida útil era algo complicado donar un ordenador ATX por tema de espacio el siguiente equipo que compré en el 2008 fue un portátil Dell XPS 1530 con un Intel Core 2 Duo T8100, 4 GiB de memoria, 320 GB de disco duro y gráfica NVIDIA 8600GT con 512 MiB, al poco tiempo de donarlo se estropeó, se quedó completamente muerto sin llegar a hacer ningún atisbo de encenderse, desde entonces no quiero nada que venga de Dell incluidos monitores tampoco me convenció pasado el tiempo de deslumbramiento inicial de su posesión la calidad de esta marca. El tercer equipo que compré a finales del 2012 también fue un portátil con la misma intención de poder donarlo llegado el momento, un Sony VAIO de 14” de resolución 1600x900 en panel TN con un Intel Core i5 3210M (Ivy Bridge, con un gráfica integrada HD4000), 8 GB de memoria con la que poder virtualizar más a gusto y un SSD Samsung 840 EVO de 250 GB SATA III (550 MB/s lectura, 500 MB/s escritura) que le puse a posteriori con el que el aumento de rendimiento en acceso a almacenamiento persistente. El SSD fue una gran mejora respecto a los discos duros mecánicos, mejor inversión que mejor procesador y más cantidad de memoria. Una pena que Sony haya abandonado el mercado de los portátiles porque con este Sony he estado realmente contento aún con algunos acabados en plástico y su pantalla TN.

    4 GiB DDR2 de memoria RAM, AMD Athlon e Intel Core 2 Duo (T8100) de anteriores equipos

    La búsqueda

    Empezaba por decidirme que formato de ordenador quería con Intentando elegir portátil, NUC o mini ITX para comprar nuevo equipo y pasado un tiempo ya casi optado por la opción que quería, Decidido a comprar un Intel NUC entre las opciones que he evaluado pasando por un análisis del Slimbook Curve que hice. Para el nuevo ordenador personal en cualquier opción que eligiese quería monitor externo, al final elegí un Benq PD2700Q con resolución QHD (2560x1440) e IPS. Descarté un ATX por tamaño e igualmente un ITX que aún siendo un formato más pequeño seguía siendo grande para mi, a pesar de que con esta opción podría elegir un AMD Ryzen con mayor cantidad de núcleos. Un portátil seguía siendo una opción válida para poder donarlo en un futuro pero ocupa cierto espacio en la mesa y no tengo intención de moverlo por lo que la función que le da nombre no me es necesaria, si eligiese uno sería un Slimbook Pro2 seguramente. Como opción me quede con algún ordenador en formato Intel NUC, en un futuro cuando ya se me quede no válido para mis usos principales lo utilizaré como ordenador servidor de archivos, de descargas u otros usos personales que pueda darle como OwnCloud o GitLab, como ocupa poco el espacio no será un problema.

    Intel NUC8i5BEK (Bean Canyon)

    Es una pena que AMD no ofrezca equipos en formato de Intel NUC, muy posiblemente lo hubiese elegido principalmente por los graves fallos de seguridad Meltdown y Spectre que se hicieron públicos a inicios del 2018 que afectan más a Intel y que por ser un fallo del hardware solo se pueden no arreglar, simplemente mitigar haciendo que sea más difícil explotarlos y con pérdida de rendimiento. Para que en el cambio del equipo fuese una mejora significativa respecto al anterior portátil Sony que tenía quería que tuviese algún núcleo más en esta guerra entre Intel y AMD por ver quien ofrece más núcleos que parece por ahora va ganando AMD con su nueva arquitectura Zen y los problemas que está teniendo Intel para bajar de los 14 nanómetros de litografía para el tamaño de los transistores.

    Además, tengo intención de intentar jugar algún juego como Diablo 3 en GNU/Linux instalando la aplicación Battle.net de Blizzard ejecutándola con Wine, PlayOnLinux/Phoenicis o Winepak, al menos en una máquina virtual con VirtualBox lo conseguí a pesar de que no llegué a jugar pero si a instalar el juego. También intentaré instalar algún juego de Steam y de GOG sobre los que si lo consigo publicaré sus respectivos artículos para explicarlo. Al Diablo es casi seguro que jugaré si me funciona en GNU/Linux el resto es más intención de querer tener tiempo para jugar a estos juegos que lo vaya a hacer. Las gráficas integradas de Intel son muy básicas y no está destinadas principalmente a juegos, al menos no triple AAA nuevos, pero son suficientes para un jugador ocasional como yo que tampoco le importa bajar la resolución y detalles gráficos para tener unos FPS razonables para jugar o se conforma con juegos con unos años.

    Los juegos que tengo en mi lista son los siguientes, juegos de rol o estrategia principalmente como se aprecia.

    Intel ha lanzado al mercado unos NUC con gráfica AMD Vega con los que si es posible a jugar bien a juegos, los NUC conocidos como Hades Canyon. Sin embargo, estos son sensiblemente caros para mi presupuesto y tienen una fuente de alimentación tan grande como el propio NUC con la que era un poco reticente. Al mismo tiempo había leído noticias de los Bean Canyon que cumplían tres requerimientos que tenía, al menos 4 núcleos y 8 hilos y una gráfica un poco mejor, de la gama Iris que tienen el doble de potencia de lo que ofrece Intel en algunos de sus procesadores y posibilidad de instalar hasta 32 GiB de memoria RAM (aunque en el vídeo de más abajo dicen que se puede instalar 64GB cuando haya módulos de 32GB, en la página oficial de Intel mencionan 32GB como máximo). Sin embargo, esto me implicaba esperar ya que estos equipos aún no estaban en el mercado, había NUCs con 4 núcleos pero con gráfica UHD 630 (GT2) no Iris Graphics 655 y que eran más caros que el precio al que finalmente han salido los Bean Canyon que llevan también 4 núcleos y la citada Iris Graphics 655 (GT3). Las gráficas Intel no son muy potentes comparadas con las dedicadas NVIDIA y AMD pero tienen muy buen soporte de controladores en GNU/Linux.

    Hay varios modelos de Bean Canyon variando el procesador que incorporan, ligeramente en tamaño si ofrecen bahía para disco de 2.5” y en el precio. El más básico NUC8i3BEK lleva un procesador i3-8109U que tiene 2 núcleos y 4 hilos con 4 MiB de cache pero la misma gráfica Iris que los modelos mayores. El NUC8i5BEK lleva un procesador i5-8259U con 4 núcleos y 8 hilos con 6 MiB de cache, la misma Iris Graphics 655 de todos estos modelos. El modelo NUC8i7BEK lleva un i7-8559U con 8 MiB de cache. Todos los modelos tienen un TPD de 28W que es algo mayor que los 15W de la generación anterior pero para que no soponga un problema el calor generado en los Bean Canyon Intel ha incorporado un ventilador de un tamaño más grande para que aún así el ruido que hace al funcionar sea menor, además ha modificado las rejillas de ventilación para permitir mayor flujo de aire.

    Todos poseen un puerto Ethernet Gigabit y WiFI AC con Bluetooth 5.0, una salida de vídeo HDMI 2.0a con soporte hasta 4K, salida Dislpay Port 1.2 integrada en el conector USB Type-C, cuatro puertos USB dos en la parte frontal (uno con soporte carga) y dos en la parte trasera, además del conector para la fuente de alimentación que tiene un tamaño pequeño comparado con la de los Hades Canyon, en la parte frontal está el botón de encendido y un LED indicador de actividad del SSD junto con la salida de audio en formato jack 3.5mm. Los modelos acabados en K son más pequeños en tamaño vertical ya que no ofrecen bahía 2.5 pulgadas para un segundo disco duro con interfaz SATA III que si ofrecen los acabados en H. En un lateral se encuentra la ranura para tarjetas SDXC con soporte UHS-I en formato microSD. En el interior están los dos slots para la memoria pudiendo instalar hasta un total de 32 GiB DDR4 a 2400Mhz, también está el conector M.2 para un SSD con interfaz NVMe de longitud 2280 o 2242, también tiene un puerto SATA III.

    Ocupan muy poco, tiene un tamaño de 11x11x3.6cm (ancho, largo, alto en centímetros) y la fuente de alimentación 13x5x3cm.

    Intel NUC Bean Canyon (slim y tall)
    Especificaciones de los modelos Intel NUC Bean Canyon

    En el momento de comercialización el modelo NUC8i3BEK tiene un precio sobre los 300€, el NUC8i5BEK sobre los 400€ y el NUC8i7BEK sobre los 500€. Los Hades Canyon llegan a los 800€ y 1000€ pero con mejor gráfica y mayor número de puertos de conexión. Con la aparición de los Bean Canyon los Baby Canyon de la generación anterior se han convertido en una opción desaconsejada por la reducida diferencia de precio, el NUC7i5BNK (i5-7260U) cuesta unos 360€ y tiene 2 núcleos menos que el NUC8i5.

    Opté por el modelo NUC8i5BEK sobre el NUC8i3BEK, por sus cuatro núcleos y sobre el NUC8i7BEH porque este no ofrece un aumente de rendimiento significativo sobre el i5 acorde a la diferencia de precio. Podría haber tenido alguna duda de si optar por el modelo sin bahía de 2.5 SATA (slim) o el modelo con bahía (tall) pero con los 500GB, si necesitase más podría ponerle además una micro SDXC de 128 GB o 256 GB con las que tendré suficiente espacio, con el disco de 250 GB del portátil Sony no llegaba a los 100 GB ocupados. Y en cualquier caso en el futuro si necesito más espacio los SSD se habrán abaratado mucho o aumentado su capacidad si continúan con su bajada de precios y aumento de capacidades a cada mes que pasa como hasta ahora.

    El precio del NUC en el momento de salida es de unos 400€ no es muy superior respecto a los que costaría un equipo ITX teniendo en cuenta que en estos hay que comprar procesador, placa base, fuente de alimentación y caja, con la diferencia de que ocupa sensiblemente más. Un AMD Ryzen 2400G, placa base MSI B450I, fuente de 450W y caja ITX el conjunto se va a aproximadamente a los mismos 400€, el Ryzen tiene mejor gráfica integrada que la Intel pero el conjunto ocupa sensiblemente mucho más espacio.

    He esperado todos estos meses hasta ahora que han aparecido a la venta en Amazon y también en Pc Componentes. Varios meses antes se han publicado varios artículos analizando en buen detalle estos modelos de NUC asi como antes la nota de prensa con la presentación oficial de Intel en el momento de su inicio de comercialización. En mi experiencia con este caso desde que aparecen las primeras noticias en los medios hasta que se empieza a comercializar y más tarde hasta que aparece en las tiendas y llega a tiendas como Amazon y Pc Componentes, puede pasar perfectamente más de medio año o un año.

    En el primer vídeo se hace una análisis del NUC y en el siguiente se puede observar como se comporta en varias pruebas de rendimiento y juegos.

    También se puede ver una comparativa del rendimiento entre los modelos de procesador de los Bean Canyon y la generación anterior. Los 2 núcleos y cuatro hilos adicionales de la octava generación se notan al comparar los resultados en multihilo.

    Memoria HyperX Impact

    Como desarrollador suelo virtualizar sistemas operativos con VirtualBox o iniciar contenedores de Docker que demandan en buena medida cantidad de memoria. Todos los equipos principalmente se me quedan pequeños por la cantidad de memoria mucho más incluso que por potencia de procesador o por la velocidad o tamaño del almacenamiento ya habiendo pasado a los SSD, incluso los 8 GiB del portátil Sony se me quedaron pequeños. La memoria DDR4 está muy cara, más incluso que en el momento de su salida (casi el doble) lo que es una anomalía en la tecnología que siempre baja de precio por la presión de los avances, los fabricantes deben estar teniendo unos márgenes de beneficios brutales con la memoria DDR4. La excusa es que han preferido producir memoria NAND y RAM para teléfonos móviles que memoria RAM para ordenadores. En el 2019 está previsto que baje de precio entre un 10% y 20% por menor demanda.

    Probablemente 16 GiB me sería suficientes pero no me importa ir a por los 32 GiB aún con el consiguiente aumento de precio. Del modelo de la memoria no tengo muchos requerimientos simplemente una que fuese de 2400Mhz y estuviese entre las memorias validada por Intel para estos NUC. Hay módulos de 16 GB que se venden sueltos o kits de dos pares de módulos para hacerlos funcionar en dual channel. Dependiendo del momento puede salir más económico comprar los dos módulos por separado o comprar un kit. La ventaja del kit es que están validados para hacerlos funcionar en dual channel y es que los módulos separados pueden tener alguna diferencia según el momento en que fuero fabricados ya que podrían haberse producido con componentes de diferentes proveedores pudiendo hacer que tengan diferencias que provocase errores en el sistema. Comprando los dos módulos en el mismo momento es raro que tenga alguna diferencia pero por asegurar se puede optar por el kit.

    Dos modelos validados por Intel compatibles con esto NUC son HyperX Impact de Kingston y los G.Skill Ripjaws más o menos en el mismo precio, los HyperX tienen algo mejor latencia aunque será poco apreciable en el uso del ordenador. Los 32 GiB en el momento en que los he comprado están entre 280 y 320€. Al final opté por la memoria HyperX Impact.

    Samsung 970 EVO M.2 NVMe

    El almacenamiento en formato SSD está bajando notablemente de precio a cada mes o par de meses que pasa. En tamaño de 250 GB ya tienen un precio muy asequible e incluso en 500 GB y 1 TB no son prohibitivos. Cambiar el disco duro por un SSD es la mejor inversión a realizar en un ordenador si la cantidad de memoria es suficiente, cualquier procesador cumple para usos ofimáticos. Se puede optar por un SSD con interfaz SATA III con una velocidad de lectura y escritura de 550 / 500 MB/s que ya es bastante rápido para muchos usuarios o en formato M.2 NVMe que ofrece sensiblemente mayores tasas de transferencia de hasta 3500 / 2500 MB/s.

    Por la cantidad de datos que tengo el tamaño que necesito está entre 250 y 500 considerando que una gran parte de los datos los tengo en dos discos duros USB externos por duplicado y el equipo solo contendría los más importantes. He barajado un M.2, ya que es el conector que ofrece el Intel NUC que he elegido, como el Samsung 970 EVO y con interfaz SATA III de 500 GB con conector M.2 había barajado el Crucial MX500. Por comparar como han evolucionado el SSD que compré en el 2014 para el Sony Vaio era un Samsung 840 EVO de 250 GB me costó 125€ y ahora un NVMe ofrece el doble de capacidad y a una velocidad sensiblemente superior y en formato SATA III doble de capacidad a un precio sensiblemente inferior.

    Al final he optado por el Samsung 970 EVO, con el Crucial con interfaz SATA III tendría creo que suficiente pero no estoy ajustando mucho el precio, al igual que en la memoria.

    Es muy posible que compre adicionalmente una tarjeta micro SDXC de 128 GB o de 256 GB como una forma de ampliar la cantidad de almacenamiento que tengo disponible y como carperta de descargas y archivos temporales. Las SDXC admiten hasta un almacenamiento de 2 TiB que en un futuro se harán más asequibles en precio.

    Desempaquetado

    Con estos componentes he realizado el pedido en Amazon ya que es la tienda que suelo utilizar para las compras en internet que hago, por comodidad, ahorrar tiempo, poder informarme lo mejor que puedo con las opiniones de otros clientes y por el amplio catálogo de productos que tiene. En total el conjunto de todos estos componentes me ha salido por unos 830€, algo más barato que el portátil Sony si tengo en cuenta el SSD que le compre luego pero sensiblemente mejor con el lustro que ha pasado entre uno y otro.

    NUC

    La caja del NUC es muy pequeña en la que se incluye el NUC y la fuente de alimentación que es mucho más pequeña que el ladrillo de los Hades Canyon.

    Caja Intel NUC8i5BEK

    Aspecto exterior del NUC.

    Aspecto exterior Intel NUC8i5BEK

    La fuente de alimentación del NUC y el soporte VESA con sus tornillos.

    Fuente de alimentación y soporte VESA

    Manuales e instrucciones del NUC.

    Manuales e instrucciones del NUC

    En el interior se aprecia el conector SATA aunque para usarlo en la versión slim hay que dejar la tapa inferior sin poner para poder añadir el disco 2.5” y los cables que necesita. La parte interior de la tapa inferior tiene una tira de un material que hace de disipador para el SSD NVMe.

    Placa base del NUC. Fuente: nucblog.net

    El ventilador es más grande que en generaciones anteriores.

    Ventilador y disipador. Fuente: nucblog.net

    Memoria

    El kit de la memoria DDR4 a 2400 Mhz no tiene nada especial. Cada módulo está empaquetado en un blister de plástico.

    Desempaquetado memoria HyperX Impact

    SSD

    El stick del SSD también es muy pequeño solo mide 8cm de largo y unos 2,5 cm de ancho.

    Desempaquetado SSD Samsung 970 EVO NVMe

    Montaje de memoria y SSD

    Montar la memoria y el SSD en el NUC es sencillo. Para acceder al interior del NUC hay que quitar los cuatro tornillos de la tapa inferior que da acceso a los slots de memoria y el conector M.2, estos tornillos tienen unos topes de modo que no se puede quitarlos completamente tampoco se perderán.

    La memoria se coloca en el slot con cierta inclinación unos 30 grados y posteriormente se empuja hacia abajo con la precaución antes de tocar el módulo desconectar el NUC de la fuente de alimentación y descargar la electricidad estática tocando algo de metal que esté conectado a tierra. No es necesario hacer mucha fuerza ni hace falta forzarlo, como los slots están uno encima del otro primero se coloca el módulo que queda abajo. Aunque no es necesario hacer mucha fuerza me ha dado la sensación de que hay que hacer más de la que debería ser necesaria.

    El SSD se coloca de forma similar, con cierta inclinación al presentar el SSD en el contector y empujando hacia los lados alternativmente hasta que quede bien insertado en el conector sin hacer mucha fuerza, finalmente se empuja hacia abajo y con un tornillo situado al final del stick fijado en su posición final para que no se mueva.

    Una vez colocados ambos elementos se vuelve a colocar la tapa inferior que hace de base en el NUC y ya está listo para el primer encendido para instalarle el sistema operativo o entrar en la BIOS con las tecla F2, F10 para seleccionar la unidad de inicio y F7 para realizar una actualización del firmware y BIOS.

    Montaje de memoria y SSD M.2

    Análisis

    El NUC es realmente pequeño con sus 11x11cm ocupa muy poco espacio, además la versión slim solo tiene 3,6 cm de altura. Para instalar el sistema operativo, en mi caso la distribución Arch Linux de GNU/Linux he tenido que deshabilitar el Secure Boot desde la BIOS a la que se accede pulsando la tecla F2 en el momento que se inicia el sistema, con la tecla F10 se puede elegir la unidad de inicio que será una memoria USB formateada con el medio de instalación, la tecla F7 sirve para instalar actualizaciones del firmware y BIOS cuando Intel los publica, el nuevo firmware se ha de guardar en una memoria USB formateada en FAT32. La BIOS es gráfica y se puede manejar con ratón con opciones que se muestran en las capturas. Por el contrario la selección de unidad de inicio y actualización del firmware son basadas en texto.

    BIOS. Fuente: nucblog.net

    Usando el script para instalar Arch Linux de forma automatizada, desatendida y personalizable conseguí instalarlo a la primera sin nada grave que no halla podido resolver. En GNU/Linux todo el hardware ha sido reconocido correctamente sin necesidad de instalar controladores adicionales. Desde la WIFI, Bluetooth, Thunderbolt, el SSD NVMe, puertos USB, tarjeta gráfica, salida HDMI y por supuesto los 32GiB de memoria. El monitor Benq con su resolución QHD también ha sido reconocido correctamente también en la instalación. Aún tengo que probarlo más pero tengo la sensación de que el texto está mejor definido en GNOME que en macOS. Lo anterior puede ser una percepción pero por otro lado me he dado cuenta es que en macOS sacando el audio por el cable HDMI no se puede controlar el volumen ni silenciarlo, en Arch Linux con GNOME si se puede controlar el volumen del sonido cuando se emite por el cable HDMI también usar las teclas para silenciarlo.

    Comparado con el anterior portátil Sony que tenía el rendimiento se nota algo mejor por el SSD NVMe con el que las aplicaciones se inician más rápido, la memoria DDR4 más veloz y mejor CPU además de ser con 4 núcleos. Aunque el disco es NVMe y ofrece más ancho de banda que SATA y es más rápido se nota algo pero la diferencia no es tan apreciable como pasar de disco mecánico a SSD. En tareas ofimáticas y de navegación el ventilador se enciende a ratos y estando en silencio se oye ligeramente pero no es molesto.

    Me están entrando dudas de si mejor hubiese optado por la versión BEH (tall) con bahía para disco SATA de 2.5” en vez de usar una tarjeta SDXC para tener más espacio, un SSD y una SDXC tienen prácticamente el mismo precio pero el disco SATA es más rápido, aunque es posible que en un futuro los SATA vayan desapareciendo por su limitación de transferencia.

    Aún tengo que probarlo más pero estos NUCs se ajusta perfectamente a lo que finalmente estaba buscando en un futuro espero que AMD desarrolle un producto similar. Para treas ofimáticas y de navegación por internet es más que suficiente, los ordenadores ATX e ITX quedan para los que quieren un rendmiento máximo o quieren jugar a las últimas novedades en juegos con grandes detalles y a altas resoluciones.

    Apple Mac mini

    Un equipo equivalente a los NUC son los Apple Mac mini. Después de unos años Apple los ha renovado como unos procesadores más recientes, más cantidad de memoria y SSD instalable. Pero a unos precios muy exagerados, tanto que el Mac mini con una configuración similar a la de este artículo del NUC saldría por 2100€, bastante más del doble. Salvo que uno quiera macOS sí o sí y uno esté muy obcecado en querer Apple no es una opción en mi opinión acertada. Paro bueno esto pasa con cualquier producto de Apple no solo es específico de Mac mini aunque como se aprecia es un ejemplo claro y sangrante al compararlo. Por si fuera poco el procesador no soporta HyperThreading o SMT con lo que son 4 núcleos y 4 hilos y la gráfica es una UHD 630 la mitad de potente que la Iris Graphics 655.

    Mac mini (2018)

    En cualquier caso no entraba dentro de mis planes un Mac mini ni aunque tuviese el mismo precio del NUC ya que prefiero GNU/Linux como detallo en Tú con tu Mac, yo con mi GNU/Linux.

    Componente Apple Mac mini Intel NUC Bean Canyon
    Ordenador900€300€ (i3), 400€ (i5), 500€ (i7)
    Memoria 32 GiB+720€+300€
    SSD 500GB+480€+120€
    Total2100€820€ (i5)

    Slimbook One

    También hubiese podido optar por un Slimbook One per no me convenció porque solo tienen un slot de memoria, admite hasta 32GB pero aún no hay módulos de esa cantidad si no es en kit, lo que en la práctica limita su memoria a 16GB. La tarjeta gráfica que tienen es una UHD 630 como comentaba la mitad de potente en teoría que la Iris Graphics 655. El diseño que tiene no es muy atractivo y no tiene tarjeta microSD como una forma de ampliarle el almacenamiento. El ONE sin descuento parte de 480€ más caro que los 400€ del Intel NUC.

    Slimbook ONE (v2)

    Nuevo escritorio

    Este es la dispoción que tenía antes con el Sony VAIO y la que tengo ahora con el NUC, la pantalla externa una Benq PD2700Q de 27” y resolución QHD (2560x1440), teclado y ratón inalámbrico V7 CKW200 a los que añadí un ratín Logitech M90 con cable básico de tres botones ya que el ratón inalámbrico en algunos momentos funciona con problemas, el teclado sin embargo funciona perfectamente, y alfombrilla para ellos junto con un concentrador USB 2.0 de Amazon Basics. He ganado mucho espacio en la mesa si en algún momento quiero trabajar en ella para otras cosas, la pantalla la tengo ahora al final de la mesa y el NUC me ocupa menos espacio que el portátil además de que puedo colocarlo en cualquier.

    He tenido que esperar muchos meses a tener esta configuración, entre elegir que quería y aguantar a que lo que quería saliese al mercado. No se si la siguiente vez esperaré tanto ya que en algunos momento se me ha hecho un tanto difícil sobre todo los fines de semana y algunos días de vacaciones. Pero bueno ya lo tengo y ahora solo me queda sacarle provecho, no tener GNU/Linux durante un tiempo ha hecho que no haya escrito artículos sobre él, en cuanto lo pruebe más a fondo muy posiblemente escriba algunos artículos, empezando por esos que comento de como poder jugar a juegos con Wine, PlayOnLinux/Phoenicis, Winepak además de Steam y GOG en algún momento más tarde.

    Intel NUC8i5BEK con Arch Linux y GNOME

    Este es el escritorio que tenía antes, con mucho espacio deshaprovechado por la ubicación del portátil.

    Escritorio con portátil

    Y el que tengo ahora.

    Escritorio con NUC

    Software. Hardware. Complete.


    Variable not found: Enlaces interesantes 340

    $
    0
    0
    Enlaces interesantesAhí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

    Por si te lo perdiste...

    .NET / .NET Core

    ASP.NET / ASP.NET Core

    Azure / Cloud

    Conceptos / Patrones / Buenas prácticas

    Data

    Web / HTML / CSS / Javascript

    Visual Studio / Complementos / Herramientas

    Otros

    Publicado en Variable not found.

    Poesía Binaria: Crear redirecciones en Apache en función de una cookie

    $
    0
    0

    Servidor de pruebas

    En estos días que asusta leer la palabra cookie en cualquier sitio. Si nos remontamos al siglo pasado, los navegadores solían preguntarnos cada vez que iban a a definir una cookie para ver si aceptábamos o no. Cosa que se terminó volviendo insostenible ya que los sitios web definían varias cookies y empotraban contenido de otros sitios que querían definir cookies y terminábamos con unas diez ventanas emergentes cada vez que entrábamos en una web. Así que, bloqueabas todas, pero las webs no funcionaban bien, y terminabas resignándote y aceptando todo.

    Aunque hoy vamos a tratar un tema diferente, vamos a darles a las cookies una utilidad extra. Aunque bien podemos conseguir el mismo efecto con un lenguaje de aplicación (Java, PHP, Python, etc), vamos a hacer que sea el mismo servidor web, en este caso Apache el que aplique una redirección en función del valor que tenga una cookie que nos manda el usuario y, un paso más, que sea transparente para él.

    ¿Para qué queremos esto?

    Podemos utilizar esta técnica para tests A/B, para probar dos versiones de la web. Aunque vamonos a un caso extremo, pero real. Imaginemos que tenemos una versión antigua de la web, programada con versiones antiguas de un lenguaje de programación y también una versión nueva programada con versiones nuevas, bibliotecas nuevas, etc, de modo que esas dos versiones no pueden estar en la misma máquina (física o virtual), de modo que tendríamos que acceder a un punto de entrada nuevo y diferente.

    También podemos hacer un acceso a un entorno de pruebas de la web, de modo que los desarrolladores puedan entrar a él, o incluso el cliente final, mientras no impedimos el acceso a los usuarios a la plataforma, haciendo que, el código sea diferente, las bases de datos sean diferentes, incluso las posibilidades de cargarnos algo también. Muchos desarrollos pueden estar pensadas para realizar pruebas, pero pensemos en plataformas como WordPress, que por unas cosas o por otras, en las que no voy a entrar, si cambiamos el host, con muchos plugins o temas podemos tener problemas.

    Y, ¿qué tal el dar una seguridad extra a nuestras aplicaciones? De forma que solo alguien que tenga la cookie pueda entrar en un área privada en donde podrá trastear con muchas cosas peligrosas de su servidor adicionalmente a tener usuario y contraseña.

    En muchos casos seguro que nos puede ser útil hacer una redirección en función de la dirección IP desde la que viene la petición, aunque en otros casos, tanto por el número de equipos que tienen que tener acceso como por el hecho de tener IPs dinámicas, no es posible.

    Vamos a ver Apache

    Para lograr esto, entramos en el VirtualHost de Apache y escribimos lo siguiente:

    1
    2
    3
    4
    5
    6
            ProxyPreserveHost On
            RewriteEngine On

            RewriteCond %{HTTP_COOKIE}    nombre_de_cookie=([^;]+)
            RewriteCond %1                 ^valor_de_cookie$
            RewriteRule         ^/(.*) http://otro_host/$1 [P,L]

    En este caso, con la directiva P para conectar vía proxy y L para que no se procesen más reglas de reescritura tras esta. Es necesario también tener los módulos rewrite y mod_proxy_http instalados por lo que antes de nada no está de más ejecutar:

    sudo a2enmod rewrite
    sudo a2enmod proxy_http
    sudo service apache2 restart

    Veamos un ejemplo completo, podemos ver este archivo de VirtualHost (lo he puesto todo en HTTP, en el mundo real deberíamos utilizar todos HTTPs):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <VirtualHost *:80>
            ServerName miweb.com
            ServerAlias www.miweb.com

            ServerAdmin security@miweb.com
            DocumentRoot /var/www/miweb.com/www
            ProxyPreserveHost On
            RewriteEngine On

            RewriteCond %{HTTP_COOKIE}    magicCookie=([^;]+)
            RewriteCond %1                 ^123456$
            RewriteRule         ^/(.*) http://10.0.1.198/$1 [P,L]

           <Directory /var/www/miweb.com/www/ >
                    Options -Indexes +FollowSymLinks +MultiViews
                    AllowOverride All
                    Require all granted
            </Directory>

            ErrorLog ${APACHE_LOG_DIR}/error.log

            LogLevel warn

            CustomLog ${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>

    En este caso, cuando entra un visitante normal, entrará directamente a la web alojada en este servidor. Web que está en /var/www/miweb.com/www, pero si viene un visitante que tenga la cookie magicCookie establecida y cuyo valor sea 123456, internamente la petición se redirigirá al 10.0.1.198, que es una IP privada que está en la misma red que el servidor y a la que normalmente los usuarios no tendrían acceso. Esta nueva dirección puede pertenecer a una máquina de la misma red, una máquina conectada a Internet, máquinas virtuales o incluso contenedores docker.

    Vamos a probarlo

    Para realizar pruebas, podemos crear un pequeño programa que defina la cookie en cuestión, por ejemplo, en PHP podríamos hacer algo así:

    1
    2
    3
    <?php

    setcookie('magicCookie','123456');

    Solo tenemos que llamar a este archivo php desde el navegador y cuando volvamos a nuestro dominio se realizará la redirección interna.

    También podemos utilizar una extensión de Chrome o Chromium llamada Cookie Inspector. Solo tenemos que activar las herramientas para desarrolladores y nos dejará establecer y modificar cookies.

    Foto principal: unsplash-logoLouis Reed

    The post Crear redirecciones en Apache en función de una cookie appeared first on Poesía Binaria.

    Picando Código: Montevideo: Conferencia Internet y Derechos Humanos

    $
    0
    0

    DATYSOC nos invita al siguiente evento:

    Conferencia Internet y Derechos Humanos

    El miércoles 13 de diciembre les invitamos a participar de una conferencia sobre Internet y Derechos Humanos.
    A partir de las 17:30 horas y hasta las 19:30 les esperamos en el Espacio Interdisciplinario de la Universidad de la República en José Enrique Rodó 1843.

    Se presentan Veridiana Alimonti, Analista Senior de Políticas en América Latina de la EFF. y Beatriz Busaniche, Presidenta de Fundación Vía Libre, Argentina.

    Entrada libre y gratuita, y los esperamos con un brindis luego de la conferencia.

     

    Fixed Buffer: Depuración remota sobre SSH

    $
    0
    0

    Depuración remota sobre SSHDespués de la entrada sobre como instalar NetCore en Linux (o sobre cualquier otro entorno), el siguiente paso lógico es poder depurar nuestro código mientras corre en Linux, como lo haríamos sobre Windows.

    Para esto, tenemos 2 opciones, utilizar Visual Studio Code o Visual Studio para hacer depuración remota sobre ssh,. En este caso, vamos a utilizar la segunda opción, ya que en la mayoría de los casos en los que usemos NetCore, correrá en un servidor sin interfaz gráfica.

    Para ello, lo primero que necesitamos es que nuestro equipo Linux tenga un servidor SSH habilitado, esto es lo que ocurre habitualmente, pero en caso de no haberlo puesto durante la instalación del OS, se puede añadir sin problema.

    Una vez dicho esto, vamos con ello.

    Proyecto

    Para poder seguir la entrada, lo primero que vamos a hacer es crear un proyecto de consola de NetCore:

    consola .net core

    Al que le vamos a poner este código:

    using System;
    using System.Threading;
    
    namespace PostDepuracionRemota
    {
        class Program
        {
            static void Main(string[] args)
            {
                int nIteraciones = 100;
                Console.WriteLine($"El programa añadirá {nIteraciones} lineas de consola, con una espera de 1 segundo entre lineas");
                for(int i = 0; i < nIteraciones; i++)
                {
                    Console.WriteLine(DateTime.Now);
                    Thread.Sleep(1000);
                }
            }
        }
    }

    Es un código muy simple, ya que la finalidad es probar la  depuración remota sobre SSH, simplemente, ejecutara 100 veces el Console.WriteLine, mostrando por pantalla la hora en la que estamos. Con esto, vamos a ganar el tiempo que necesitamos para asociarnos al proceso remoto. Si lo ejecutamos tal cual, tendremos una salida parecida a esta:

    Ejemplo depuración remota

    Una vez que tenemos esto, lo colocamos en nuestro servidor, y vamos al lío!!!

    Depuración remota sobre SSH

    Visual Studio 2017 añade varias opciones para asociarnos a un proceso en ejecución, para ello, desde el menú “Depurar”, vamos a la opción “Asociar al proceso…”, o pulsamos el atajo “Ctrl+Alt+P

    Asociar al proceso

    Eso, nos va a mostrar una nueva ventana:

    VentanaAsociar

    En ella, seleccionamos el tipo de conexión SSH y ponemos la dirección del servidor. Con eso, al pulsar actualizar, se nos mostrará una nueva ventana para pedirnos los datos de conexión:

    ventanaDatosSSH

    Basta con que rellenemos los campos con los valores de conexión a nuestro servidor, y acto seguido,  (igual hay que pulsar sobre actualizar) se nos mostraran los procesos activos en el servido:

    ProcesosActivos

    Vamos a utilizar la opción de filtro, para buscar los procesos “dotnet”:

    filtro

    Seleccionamos el proceso que queremos depurar, y esto nos lanza una ultimo ventana, en la que nos pide que le indiquemos como queremos depurar:

    Modo

    Tenemos que seleccionar “Managed”. Al seleccionar el proceso, vemos que se asocia a la ejecución, y nos permite depurar el ejecutable de manera remota sobre ssh:

    Breakpoint

    Aclaraciones

    En caso de necesitar instalar componentes, Visual Studio se encarga de descargarlos e instalarlos sin necesitar nada por nuestra parte. Esto es así siempre, salvo que nos falten paquetes que se consideran básicos, como pueden ser el servidor SSH, curl o wget, o unzip. En caso de que nos falte alguno o todos ellos,  debemos instalarlos nosotros, o cuando intentemos asociarnos se mostrara un error parecido a este:

    Error Paquetes

    /home/username/.vs-debugger/GetVsDbg.sh -v vs2017u5 -l “/home/username/.vs-debugger/vs2017u5”

    Esto se soluciona fácilmente instalando todo lo que nos falte con el comando:

    sudo apt-get install openssh-server unzip curl

    Espero que haya sido de utilidad, aunque le daremos uso en siguientes entradas cuando creemos DLL de C++ y las consumamos en NetCore, para poder comprobar en caso de que tengamos algún problema.

    **La entrada Depuración remota sobre SSH se publicó primero en Fixed Buffer.**

    Metodologías ágiles. De lo racional a la inspiración.: Open Space, para un roto o para un descosido

    $
    0
    0
    Hemos hablado varias veces aquí ya de los Open Space como un formato increible para la organización y facilitación de conferencias. En Agile-Spain hemos organizado ya tres a nivel nacional, y han surgido multitud de pequeños "opens" para tratar muchos temas alrededor del agilismo. Si no sabes qué es un Open Space, echa un ojo a esta explicación, o no entenderás demasiado el siguiente post :) Pero
    Viewing all 2708 articles
    Browse latest View live