Weblogs Código

Cuaderno de software

Rise and fall of Coconut

mayo 25, 2017 05:16

(originally written in spanish by Luis here)

Coconut? Turns out that you can’t boil down witty brainwork and complex concepts to just one word

A long time ago, some folks came together to talk about something they were doing each one on their own. They talked and talked. They worked over complex concepts and specific contexts. They didn’t chew only over what they did; they discussed the reasons why they were doing it as well.

They decided to name the whole effort “Coconut”. And, to summarise the whole process, they wrote the “Coconut Manifest” together with its 12 coconutting principles.

But guess what: IT TURNS OUT THAT PEOPLE ARE NOT USING THE COCONUT CONCEPT AS IT WAS CONCEIVED. The result is that, when people talk about “coconutting”, everyone understands something different. Some even think that “doing Coconut” is a synonym of “thinking”. But you cannot really replace “thinking”.

As one digs deeper into Coconut, its meaning starts emerging… until you realize that the truth you have reached is the original essence that the Coconut´s founders brought to light.

Coconut is now dead. It doesn’t mean anything. What’s next?

» Leer más, comentarios, etc...

Cuaderno de software

El auge y declive de Cocotero

mayo 24, 2017 05:52

¿Cocotero? resulta que con una palabra no puedes resumir sesuda reflexiones ni conceptos complejos.

Hace muchos años hubo unos cuantos que se juntaron para hablar de algo que estaban haciendo cada uno por su cuenta. Hablaron durante días. Trabajaron sobre conceptos complejos, que dependían de ciertos contextos concretos. Hablaron no sólo de qué hacían, sino de por qué.

Decidieron llamar a todo aquello (por qué, contexto, concepto, etc…): Cocotero.  Y como resumen, escribieron el Manifiesto Cocotero, con sus 12 principios cocoterizantes.

Pues bien: RESULTA QUE LA GENTE NO USA EL TERMINO COCOTERO TAL Y COMO FUE CONCEBIDO. Y cuando la gente habla de “cocoterizar”, cada uno entiende lo que le da la gana. Hay gente que incluso cree que “hacer cocotero” sustituye a pensar. Pero nunca puedes sustituir pensar.

Cuando uno profundiza en Cocotero, va cambiando su concepción del mismo… para acabar descubriendo que la verdad a la que acaba de llegar, es la esencia original de sus fundadores.

Cocotero ha muerto. Ya no significa nada. ¿Qué es lo siguiente?

» Leer más, comentarios, etc...

Adrianistán

Triángulo de Sierpinski en JavaScript

mayo 24, 2017 02:28

Un amigo me propuso esta mañana que viera un vídeo de Numberphile, concretamente uno titulado Chaos Game. El vídeo es bastante interesante y habla de como de una aparente aleatoriedad es posible sacar fractales y patrones regulares. Esta misma mañana al llegar a casa y antes de comer me he picado y me he puesto a implementar el algoritmo en JavaScript usando el Canvas de HTML5. El resultado lo tenéis aquí:

http://adrianistan.eu/sierpinski/

Y el código que lleva es el siguiente:

const COLOR_LIST = ["red","green","yellow","pink","brown","purple","cyan","blue","orange"];

function punto(x,y){
    var p = {
        x:x,
        y:y
    };
    return p;
}

function puntoMedio(p,q){
    var m = {
        x: Math.round((p.x+q.x)/2),
        y: Math.round((p.y+q.y)/2)
    };
    return m;
}

function getRandomColor(){
    return COLOR_LIST[Math.floor(COLOR_LIST.length * Math.random())];
}

function dibujarPunto(ctx,p,size){
    ctx.fillStyle = getRandomColor();
    ctx.fillRect(p.x,p.y,size,size);
}

function $(id){
    return document.getElementById(id);
}

function get(id){
    return Math.round(document.getElementById(id).value);
}

function main(){
    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");

    var interval;

    $("start").addEventListener("click",function(){

        var size = get("size");
        var vertex = [punto(get("a-x"),get("a-y")),punto(get("b-x"),get("b-y")),punto(get("c-x"),get("c-y"))];

        let p = punto(get("s-x"),get("s-y"));

        dibujarPunto(ctx,p,size);

        interval = setInterval(function(){
            var q = vertex[Math.floor(3*Math.random())];
            p = puntoMedio(p,q);
            dibujarPunto(ctx,p,size);
        },get("speed"));
    });

    $("stop").addEventListener("click",function(){
        clearInterval(interval);
    });

    $("reset").addEventListener("click",function(){
        ctx.fillStyle = "white";
        ctx.fillRect(0,0,600,600);
    });
}

window.addEventListener("DOMContentLoaded",main);

Con distinto número de vértices existen otros fractales, también muy chulos. Incluso en el vídeo de Numberphile realizan un fractal con un gran parecido a una hoja de helecho, usando dos triángulos y una ligera modificación del algoritmo.

Un saludo y soñad con fractales.

La entrada Triángulo de Sierpinski en JavaScript aparece primero en Blog - Adrianistan.eu.

» Leer más, comentarios, etc...

Variable not found

Ordenar por un campo enum con WebGrid

mayo 23, 2017 08:59

ASP.NET MVC 5El amigo José Antonio M. A., alumno de mi curso de ASP.NET MVC 5 en CampusMVP, me envió hace unos días una pregunta que he creído interesante comentar por aquí porque probablemente pueda ayudar a alguien más.

La cuestión que planteaba era relativa al mal funcionamiento de WebGrid cuando mostramos un campo de tipo enum y queremos ordenar por el mismo. Poco más o menos, me lo comentaba de la siguiente forma:
He incluido un campo enum en la clase del modelo y lo he incluido como columna en WebGrid.
[…]
Todo funciona bien menos el WebGrid, que no me ordena por esa columna. Al hacer click en ella ordena de forma correcta ascendentemente pero al hacer click otra vez no te ordena de forma descendente, mirando la url se ve que sortOrder no varía sigue siendo ASC. si lo cambio a mano a desc me lo ordena bien. ¿Es que el webgrid no ordena enumeraciones? ¿Cuál sería la solución, si quiero ordenar?
Obviamente, el hecho de que al cambiar a mano el parámetro sortOrder todo funcionara bien, dejaba de manifiesto que el problema no estaba en el controlador ni en el modelo, dejando la vista como única sospechosa de provocar ese problema.

Mis primeras respuestas iban orientadas a buscar un pequeño fallo en la forma de usar WebGrid o similar, porque me parecía algo bastante extraño, y, sobre todo, me parecía raro que no me hubiera pasado antes. José Antonio comentó, además, que había encontrado referencias por la red de que WebGrid tenía este problema, y que podía solucionarse si se forzaba una conversión de la enumeración a string a la hora de pasar los datos a la vista (!).

Y tras hacer varias pruebas, efectivamente, parece que algo hay. No sé si categorizarlo como bug del componente, o simplemente un comportamiento algo oscuro y poco previsible del mismo, pero en cualquier caso es interesante conocer este problema para poder atajarlo con éxito.

El motivo

Resulta que WebGrid guarda internamente una lista con los nombres de las columnas que serán gestionadas por este componente. Las columnas que no sean incluidas en esta lista no podrán ser utilizadas para realizar operaciones como la ordenación.

Los nombres de columna se establecen durante la llamada al método Bind(), de la siguiente forma:
WebGrid grid = new WebGrid(rowsPerPage: Model.PageSize);
grid.Bind(
Model.People,
columnNames: new[] {"name", "lastname", "email"},
autoSortAndPage: false,
rowCount: Model.PeopleCount
);
Observad que esto es independiente de las columnas que definamos más adelante para visualizar en el grid, durante la llamada a grid.GetHtml(). Estamos en un momento anterior, cuando "bindeamos" el grid a la colección de datos que mostrará.

Bien, el caso es que normalmente no lo hacemos así. Lo habitual es no suministrar el parámetro columnNames al método Bind(), asumiendo que este binding lo realizará el sistema de forma automática por nosotros, tomando por defecto como columnas todas las propiedades de los objetos que vamos a mostrar en la rejilla.

Y ahí es donde viene el problema. El siguiente método del código fuente de WebGrid, decide qué tipos de datos son aceptados en ese binding automático:
private static bool IsBindableType(Type type)
{
Debug.Assert(type != null);

Type underlyingType = Nullable.GetUnderlyingType(type);
if (underlyingType != null)
{
type = underlyingType;
}
return (type.IsPrimitive ||
type.Equals(typeof(string)) ||
type.Equals(typeof(DateTime)) ||
type.Equals(typeof(Decimal)) ||
type.Equals(typeof(Guid)) ||
type.Equals(typeof(DateTimeOffset)) ||
type.Equals(typeof(TimeSpan)));
}
Este método es invocado durante la inicialización de WebGrid para cada propiedad presente en los objetos que van a ser mostrados en la rejilla. Las columnas que superen las condiciones serán introducidas en la lista de columnas válidas, y ésta será utilizada en distintos puntos para comprobar si existen los campos con los que pretendemos realizar operaciones, como la ordenación.

Las soluciones

Si os encontráis con este problema, existen varias soluciones; podéis usar la que más os guste, menos pereza os dé o la que mejor encaje en vuestro proyecto, pues el resultado será el mismo.

Como hemos visto anteriormente, los enum no son incluidos por defecto simplemente porque no están en la lista de tipos admitidos. Lo único que habría que hacer para que WebGrid soportase enums por defecto sería añadir la condición type.IsEnum al retorno de este método:
private static bool IsBindableType(Type type)
{
    ...
return (type.IsPrimitive ||

type.IsEnum || // <-- Allow enums
type.Equals(typeof(string)) ||
type.Equals(typeof(DateTime)) ||
type.Equals(typeof(Decimal)) ||
type.Equals(typeof(Guid)) ||
type.Equals(typeof(DateTimeOffset)) ||
type.Equals(typeof(TimeSpan)));
}
Pero bueno, como no siempre tenemos el código fuente de WebGrid a mano y no siempre estamos dispuestos a introducir una copia personalizada de este componente en nuestro proyecto, así que lo más conveniente es utilizar otro tipo de soluciones.

Una posibilidad consistiría simplemente en eliminar el tipo enum de los objetos a mostrar en la rejilla. Por ejemplo, podemos enviarlos a la vista cambiando los tipos del Modelo, transformándolos o proyectando previamente a tipos de datos soportados, como string o int. Es sencillo de aplicar, aunque puede resultar intrusiva y también algo trabajosa.

Otra posibilidad se puede inferir directamente de los motivos que hemos comentado más arriba. Si el problema se debe a que no hemos especificado las columnas concretas en el método Bind(), hagámoslo y tendremos el problema solucionado. La única contraindicación destacable es que es algo farragosa, y puede ser propensa a fallos, pues debemos mantener esta lista de nombres de columna sincronizada con los nombres de las propiedades de los objetos (aunque quizás podría aliviarse algo usando el operador nameof de C#):
WebGrid grid = new WebGrid(rowsPerPage: Model.PageSize);
grid.Bind(
Model.People,
columnNames: new[] {"name", "lastname", "email", "persontype"},
autoSortAndPage: false,
rowCount: Model.PeopleCount
);
Por último, también podemos utilizar un truquillo rápido (¿o más bien debería decir un hack?) que parece que ha funcionado en las pruebas que he hecho: establecer manualmente la propiedad SortColumn del objeto WebGrid al campo de ordenación actual, justo después de hacer el Bind():
WebGrid grid = new WebGrid(rowsPerPage: Model.PageSize);
grid.Bind(Model.People, autoSortAndPage: false, rowCount: Model.PeopleCount);
grid.SortColumn = Request["sort"];
De esta forma forzamos a que WebGrid reconozca el campo de ordenación actual aunque éste no se encuentre en la lista de columnas bindeadas :)

¡Espero que os sea de ayuda!

Publicado en Variable Not Found.

» Leer más, comentarios, etc...

Adrianistán

¿Nos vemos en la LechazoConf?

mayo 22, 2017 02:27

El próximo sábado 27 de mayo tendrá lugar en Valladolid la LechazoConf. Uno de los mayores eventos de informática de la región.

Este evento cuenta con ponencias muy interesantes sobre el éxito y el fracaso (o al menos interesantes sobre el papel). Además, se podrá comer lechazo.

Yo estaré por allí, gracias a una invitación que tengo, así que si quieres: hablarme, comentarme, explicarme, insultarme, agradecerme, increparme, consolarme, abrazarme, besarme, matarme, vacilarme, comer unas patatas juntos, pasear juntos, debatir sobre metafísica, hacer travesuras por la ciudad o simplemente explicarte como conseguir la clave del WiFi o explicarte como instalar Windows sin que parezca que estés haciendo el vago, no dudes en buscarme.

PD: Me llamo Adrián Arroyo, no creo que me lo cambie para cuando sea la Lechazo.

PD2: Aunque nos hagamos muy buenos amigos, recuerda que mi lechazo es mi lechazo y el tuyo el tuyo

La entrada ¿Nos vemos en la LechazoConf? aparece primero en Blog - Adrianistan.eu.

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 283

mayo 22, 2017 06:55

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

.NET/.NET Core

ASP.NET/ASP.NET Core

Azure / Cloud

Conceptos/Patrones/Buenas prácticas

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Cross-platform

Otros

Componentes/bibliotecas


Por último, ahí va una ilustración que seguro que ya habéis visto alguna vez, pero creo que es bastante útil para aclarar conceptos como On Premise, IaaS, PaaS y SaaS, muy utilizados a la hora de definir los modelos de prestación de determinados servicios:


Fuente: Pizza as a Service (Albert Barron)

Publicado en Variable not found

» Leer más, comentarios, etc...

Blog Bitix

Sobre el ataque de ransomware que ha sufrido Telefonica y otras empresas

mayo 21, 2017 09:45

Microsoft
Windows 10

El día 12 de mayo de 2017 se produjo un ataque informático de tipo ransomware que afectó a varias empresas entre ellas Telefonica. El ataque se aprovecha de una vulnerabilidad conocida en los sistemas con el sistema operativo Windows no parcheados y vulnerables y para la cual Microsoft ya había publicado un parche de seguridad que la corregía. El programa ransomware WannaCry era extremadamente peligroso ya que cifra los archivos y documentos locales o en unidades a las que tuviese acceso el sistema afectado solicitando para recuperarlos 300 dólares en bitcoins.

La peligrosidad de este ransomware radica en que cifra los datos que es una de las cosas más importantes de un sistema, también causa que el sistema deje de prestar su servicio con los quebrantos que puede ocasionar si el buen funcionamiento del sistema es crítico en una empresa. Una vez un sistema es corrompido la forma de no ser víctima de la extorsión para recuperar los archivos es a través de una copia de seguridad una vez reinstalado Windows.

Captura del ransomware WannaCry en un sistema infectado

El programa ransomware se introduce en los los sistemas aún vulnerables conectados a internet o porque un usuario lo activa por ejemplo mediante un clic en un correo electrónico en un sistema interno no conectado directamente a internet. Una vez un sistema es infectado se transmite al resto de equipos vulnerables a los que tenga acceso de la red local, multiplicando el problema.

Unos dicen que el problema es de Windows pero al ser un sistema operativo mayoritario este es más interesante de atacar por los delincuentes informáticos. También en defensa de Windows unos dicen que Microsoft ya publicó un parche de seguridad que lo resolvía y que la culpa es de las empresas que no los mantiene actualizados pero no es tan sencillo, algunos sistemas son críticos o desempeñan funciones importantes por los que una actualización que cause problemas no es plausible ya que genera problemas y costes entre otras cosas, la opción es mantenerlos desactualizados hasta que las actualizaciones se comprueben que no causan problemas.

Son numerosos los medios que se han hecho eco del acontecimiento tecnológico de esa semana:

Quizá alguien piense que un sistema con GNU/Linux hubiese sido distinto pero no, un sistema GNU/Linux desactualizado es igual de vulnerable, por el hecho de ser GNU/Linux no es más seguro. Lo que hay que implementar son procedimientos y aplicar medidas para evitar estos fallos de seguridad y para minimizar las vulnerabilidades de los sistemas cualquiera que sea el sistema utilizado. A pesar de lo anterior una muestra de la seguridad que ofrece GNU/Linux que hay que destacar es que es un sistema utilizado en una gran mayoría de servidores importantes de los que ofrecen servicios en internet u otros servicios críticos, correctamente configurados y mantenidos funcionando de forma segura.

En unas empresas y sociedad cada vez más dependientes de la tecnología un ataque como este puede causar importantes daños como ha sido en el caso del sistema de salud británico, en empresas como en el mismo caso de Telefonica ha obligado a apagar sistemas para evitar la propagación y preventivamente males mayores impidiendo trabajar con normalidad a un importante número de empleados de la empresa. El ataque de WannaCry es una advertencia de lo que puede provocar un caso peor en el futuro, y este ransomware cuando actúa es evidente que se está sufriendo, otros ataques menos notorios pueden pasar inadvertidos. Algo que ocasionará lo sucedido es que se dedicarán más recursos a la seguridad.

GNU/Linux es un sistema más abierto y público que Windows, su código fuente está disponible para ser analizado por cualquiera con los conocimientos de programación suficientes y cuando un fallo de seguridad es descubierto el parche de seguridad es publicado no mucho tiempo más tarde sin depender de los intereses de una única empresa. Windows al ser más cerrado y desarrollado por una empresa que tiene su control absoluto, del cual dependen otras empresas y organizaciones gubernamentales, algunos fallos de seguridad son ocultados pero explotables hasta que son resueltos por el parche de seguridad.

Pero sin duda en cualquiera de los dos sistemas operativos el usuario o administrador del sistema es una pieza clave para mantener su seguridad como comento en el artículo Distribuciones GNU/Linux, ¿más seguras que Windows?.

» Leer más, comentarios, etc...

Blog Bitix

Sobre el anuncio de Shuttleworth de abandonar Unity y Mir y volver a GNOME en Ubuntu

mayo 20, 2017 09:45

Ubuntu
Canonical

Hace unas semanas el fundador de Ubuntu, Mark Shuttleworth, una de las distribuciones más populares de GNU/Linux publicaba que abandona dos de sus proyectos más conocidos, la interfaz Unity y el servidor gráfico Mir. Uno de ellos la interfaz Unity en favor de GNOME que se materializará en la siguiente versión de Ubuntu, la 17.10 o 18.04 LTS. Al mismo tiempo daba a conocer que abandonaba el desarrollo de su servidor gráfico Mir en favor de su alternativa y más aceptada en la comunidad Wayland.

El abandono de un proyecto no es nada nuevo en el software libre o en el software a secas, unos tienen éxito y otros perecen y volverá a pasar en el futuro. En cualquier caso queda claro que Ubuntu, Canonical o Shuttleworth no han tenido éxito para continuar y finalizar el desarrollo de Mir, un motivo porque su desarrollo requiere gran esfuerzo en desarrolladores dedicados y también económicamente que no le deben sobrar. Tampoco ha sido un proyecto aceptado por la comunidad, finalmente el vencedor a sido GNOME y Wayland más apoyados por RedHat empresa con gran éxito a nivel empresarial, al igual que pasó con el sistema de inicio Upstart abandonado en favor de systemd y en el futuro quien sabe si pasará algo parecido con la forma de distribuir software con snaps y su equivalente Flatpak. Tampoco, lo que no ha conseguido Shuttleworth es tener el apoyo de la comunidad e incluir en sus desarrollos al resto de empresas del mundo del software libre como RedHat.

Creo que Shuttleworth tiene razón para apostar por la convergencia ya que coincido en que la convergencia será la siguiente disrupción tecnológica y la empresa que primero consiga implementarla con éxito tendrá una ventaja sobre el resto y estará en la mejor posición para dominar el mercado tecnológico durante la siguiente década. La que llegue tarde corre peligro de perder gran parte de su relevancia o incluso desaparecer del primer plano como le sucedió a Nokia con la llegada de los smartphones por parte de Apple o con la llegada tardía de Microsoft con su sistema operativo para estos dispositivos sin éxito y con una cuota de mercado mínima. Parece que Microsoft está bien posicionada en este caso para la convergencia y ya se están publicando algunos artículos indicando que los procesadores basados en ARM como es el Snapdragon 835 serán capaces de ejecutar Windows 10 y programas x86 vía emulación con un rendimiento satisfactorio, en el momento que esto se comercialice incluso el dominio de Intel en el mercado de procesadores puede verse amenazado.

La apuesta de Unity en Ubuntu como entorno de escritorio por defecto no ha sido bien acogido por sus usuarios y una buena cantidad de ellos han migrado a distribuciones como Linux Mint que debe en gran parte a su éxito al no éxito de Unity y en otra parte a las críticas que recibió en su día GNOME. La vuelta a GNOME que inicialmente era un escritorio aún inmaduro, ya desde 3.18 añadió multitud funcionales y realizado una gran mejora que puede convencer a alguno de sus antiguos usuarios a regresar a Ubuntu. En las últimas versiones de GNOME se van puliendo detalles de menor importancia que en anteriores versiones pero haciendo cada vez más de GNOME un escritorio muy completo y bien integrado.

Otro de los motivos que se ha comentado es que Shuttleworth quiere que su empresa empiece a cotizar el bolsa y para mejorar su valoración los inversores considerarían en mejor grado deshacerse de los proyectos que no tiene éxito para centrarse en las áreas que sí como el internet de las cosas y la computación en la nube.

Aunque Canonical haya abandonado estos dos proyectos hay que reconocerle su trabajo para intentar innovar y liderar con dos proyectos que hubiesen contribuido a Linux y el software libre al igual que hay que agradecerle a popularizar aún más Linux con Ubuntu. En cualquier caso parece que los proyectos continuarán por parte de la comunidad pero ahora sin el apoyo oficial de Canonical.

» Leer más, comentarios, etc...

Picando Código

Humble Indie Bundle 18

mayo 19, 2017 03:00

Humble Indie Bundle 18

El humilde paquete de videojuegos multiplataforma independientes cumple la mayoría de edad en cuanto a versiones de su formación original: Humble Indie Bundle 18. En años hace 7 del primer Humble Indie Bundle. Desde entonces Humble Bundle se ha transformado en una tienda completa de videojuegos y otros productos multimedia. Además de paquetes de muy variadas naturalezas (estudios de videojuegos en particular y temáticos), también han habido ventas de música, libros y cómics.

Pero los Humble Indie Bundle siguen manteniendo las características principales de aquel primero:

  • Juegos multiplataforma (GNU/Linux, Mac OS y Windows)
  • Sin DRM, y pagando más de $1, obtenemos claves de Steam
  • Elegimos cuánto pagar y dónde va el dinero. Los Humble Bundle nos dejan repartir el dinero que paguemos entre los desarrolladores, el Humble Store o distintas caridades.

Al igual que en aquel primer Bundle, las dos caridades a las que podemos donar son EFF y Child’s Play. También se agregó la posibilidad de elegir otra(s) caridad(es) donde destinar nuestro dinero.

Uno de los cambios que ha tenido el bundle en los últimos tiempos es que separan distintas tandas de juegos que podemos comprar. Pagando cualquier cantidad podemos obtener estos primeros tres títulos:

Ziggurat

Un FPS de exploración de calabozos, con hechizos, enemigos, level-up, calabozos al azar, trampas, jefes, y zanahorias. Una combinación del género de disparos en primera persona con roguelike. Todavía no lo he probado, no sé si es mi tipo de juego, pero espero eventualmente darle una oportunidad.

Windward

Tomamos control de un navío para embarcarnos en una aventura dentro de un mundo único generado dinámicamente. Diseñado para jugar cooperativo, aunque también se puede jugar de manera individual. Podemos armar nuestra facción y salir a luchar contra piratas, hacer trueques en distintos pueblos, questos o simplemente explorar.

Me resultó sumamente interesante la idea, y lo estuve jugando un rato. Es bastante entretenido y tiene ese aire simulador que te mantiene enganchado. Más adelante los pueblos van creciendo y ofreciendo más quests, recursos e ítems, hasta poder mejorar nuestro barco mismo. Probablemente vuelva a jugarlo, y me interesa ver eso de jugar en modo cooperativo.

SteamWorld Heist

Comandamos a una tripulación pirata a vapor con estrategia basada en turnos, con la particularidad de que apuntamos las armas de los robots a mano. Se supone que es amable con los novatos pero desafiante para veteranos. Tengo SteamWorld Dig en mi cuenta de Steam hace un buen tiempo y no lo he jugado, no sé si me llama la atención este juego…

Pagando más del promedio, obtenemos otros tres títulos confirmados y algún título más en unos días. Al momento de escribir esto el promedio estaba en $ 7.52

Kentucky Route Zero

Aventura gráfica del tipo point-and-click (a lo Monkey Island), centrado en la caracterización, atmósfera y narración en vez de puzzles o desafíos de destreza. Tengo en mi lista Day Of The Tentacle Remastered todavía por terminar, así que dudo que llegue a este juego en breve…

Beholder

Este juego me atrapó desde la introducción:

En un mundo distópico donde el estado controla cada aspecto de la vida de los ciudadanos, es difícil ser buena persona cuando tu trabajo es espiar a la gente… Como gerente de una casa de apartamentos tenemos el poder de espíar, allanar, robar, vender, encontrar cosas prohibidas, reportar a las autoridades, extorsionar o arriesgar nuestra vida para salvar a los residentes de la casa. La premisa: en este mundo oscuro donde la privacidad está muerta, ¿qué tipo de persona serías?

La ambientación va muy bien con esta idea orwelliana, y se nota que saca mucho de 1984 (incluso la fecha de las directivas del gobierno muestran que el año en el juego es 1984). Un juego muy interesante donde tenemos que elegir si ser un ciudadano ejemplar para el estado totalitario o un rebelde.

Goat Simulator

Este simulador de cabra nos trae lo más reciente en tecnología de simulación de cabras. Se trata de destruir la mayor cantidad de cosas posible siendo una cabra. Se le compara con los juegos de skate, solo que en vez de hacer trucos, rompemos cosas. Entre las características del juego, los desarrolladores destacan que podemos ser una cabra. Además del juego, se incluye todo el DLC y el soundtrack.

Pagando $ 13 o más, obtenemos el título Owlboy. Desde que me enteré que había una versión para Linux lo agregué a mi wishlist de Steam.

Los desarrolladores lo catalogan como una carta de amor al pixel art para nuevas audiencias. Y es que el arte es de destacar. Recuerda a las mejores épocas de los juegos 16 bit. Se trata de una aventura donde podemos volar y explorar un mundo en las nubes. Podemos cargar amigos con distintas habilidades para que nos acompañen a explorar, vencer enemigos y resolver puzzles. ¡Sumamente recomendable!

Humble TinyBuild Bundle

Humble TinyBuild Bundle

Otro paquete que compré hace poco es el Humble TinyBuild Bundle. El estudio responsable de No Time To Explain, ha crecido bastante en los últimos tiempos, dedicándose ahora a la publicación de juegos de terceros. Este paquete incluye varios títulos interesantes. Cuidado que no todos son multiplataforma. Recomiendo específicamente No Time To Explain, y SpeedRunners parece bastante divertido para jugar con amigos. También está Punch Club que tengo pendiente probar. Otros que probé y entretienen bastante son Party Hard (somos el asesino en una fiesta y debemos matar a todos los asistentes sin que nos agarre la policía) y The Final Station.

Un montón de juegos nuevos agregados a mi biblioteca, que con suerte algún día tendré oportunidad de jugar…

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti)

Reflexiones sobre FileOptimizer

mayo 16, 2017 09:34

Desde la evolución de FileOptimizer, no os ponía un poco al tanto del estado del proyecto. Desde entonces, han ido ocurriendo bastantes cosas que me han hecho pensar acerca de él, unas reflexiones, que me gustaría compartir con vosotros. Me resulta muy curioso, que la fecha de lanzamiento de FileOptimizer 9.00, fuera el 15 de […]

La entrada Reflexiones sobre FileOptimizer aparece primero en Bitácora de Javier Gutiérrez Chamorro (Guti).

» Leer más, comentarios, etc...

Variable not found

Retargeting y multitargeting en proyectos ASP.NET Core

mayo 16, 2017 06:55

ASP.NET CoreA la hora de iniciar un nuevo proyecto ASP.NET Core, una de las primeras decisiones que debemos tomar es si el target de éste será .NET Core o .NET Framework.

Muchas veces esto dependerá de los requisitos y el entorno del proyecto; por ejemplo, si nos interesa la capacidad para ejecutarlo o desarrollarlo sobre entornos Linux o Mac, nos tendremos que decantar por .NET Core, pues el framework completo sólo está disponible para Windows. También podemos encontrarnos con que necesitamos (re)utilizar componentes o bibliotecas que aún no han sido portadas a .NET Core, por lo que en este caso el target será .NET Framework (bueno, esto cambiará bastante con la llegada de Net Standard 2.0, pero de momento es lo que hay).

En cualquier caso, la decisión la tomamos justo en el momento de crear el proyecto en Visual Studio, al seleccionar la plantilla que usaremos como base:

Cuadro de diálogo de creación de proyecto ASP.NET Core en Visual Studio 2017

Sin embargo, conforme el proyecto avanza, puede que esta decisión que tomamos tan al principio no sea del todo válida: quizás en su momento elegimos .NET Core, pero ahora debemos cambiar a .NET Framework. O al contrario, porque ahora necesitamos que nuestra aplicación sea multiplataforma. O tal vez necesitemos las dos cosas al mismo tiempo por si acaso…

Nota: aunque aún pululan por ahí aplicaciones creadas con versiones preliminares del SDK, basadas en el difunto project.json, aquí utilizaremos la versión 1.0 del SDK, que ya utiliza el nuevo .csproj. Si todavía no has migrado, ya estás tardando ;)

1. Cambiar de target .NET Core a .NET Framework, o viceversa

Imaginemos un proyecto creado inicialmente para .NET Core. Si usamos Visual Studio 2017, veremos en el explorador de soluciones que las dependencias están divididas en dos categorías: NuGet y SDK. En la primera encontraremos referencias hacia los paquetes requeridos por el proyecto, mientras que en la segunda se hace referencia al runtime y bibliotecas de .NET Core, incluidas en Microsoft.NETCore.App:

Carpeta "Dependencies" de un proyecto targeting .NET Core en el explorador de soluciones de Visual Studio

En este caso, en el archivo de proyecto TuAplicacion.csproj encontraremos algo como lo siguiente (los números de versiones mostrados pueden variar dependiendo de la versión de .NET Core y ASP.NET Core que estemos utilizando):
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp1.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1" />
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.1.0" />
</ItemGroup>

</Project>
Como se puede intuir, el retargeting a .NET Framework básicamente consiste en modificar el target framework moniker (TFM, o identificador de framework) "netcoreapp1.0" que se especifica en la etiqueta <TargetFramework> y sustituirlo por el identificador de la versión del framework .NET que vayamos a utilizar (podéis ver una lista de opciones aquí).

Por ejemplo, si modificamos de la siguiente forma el archivo .csproj indicaremos que el target de nuestro proyecto será .NET 4.6.1 usando el TFM "net461":
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>

...
</Project>
Obviamente, podríamos utilizar otros TFM como "net462" o "net47" (para la última versión del framework). El único requisito es que lo tengamos instalado en nuestro equipo porque de lo contrario aparecerá un error como el siguiente cuando se intenten restaurar las dependencias.:
Error MSB3644: The reference assemblies for framework ".NETFramework,Version=v4.7" were not found. To resolve this, install the SDK or Targeting Pack for this framework version or retarget your application to a version of the framework for which you have the SDK or Targeting Pack installed. Note that assemblies will be resolved from the Global Assembly Cache (GAC) and will be used in place of reference assemblies. Therefore your assembly may not be correctly targeted for the framework you intend.
Al hacer este cambio el proyecto ya no requeriría el uso de .NET Core, por lo que desaparecerá la referencia al paquete Microsoft.NETCore.App, siendo sustituida por referencias a los ensamblados requeridos del framework .NET:



Ya hemos visto cómo modificar el target del proyecto desde .NET Core a .NET framework, pero, ¿y si queremos hacerlo justo al contrario? Pues como seguro podréis adivinar, si queremos cambiar de .NET Framework a .NET Core, el cambio consistirá en establecer el tag <TargetFramework> apropiadamente, por ejemplo usando el TFM "netcoreapp1.0" o el correspondiente a la versión de .NET Core que tengamos instalada en nuestro equipo.

2. Multitargeting: proyectos para .NET Core y .NET Framework al mismo tiempo

Lo que hemos visto anteriormente está bien si nos interesa que nuestro proyecto tenga un único target, es decir, que esté preparado para ejecutarse bien en .NET Core o bien .NET framework, pero no ambas cosas a la vez. Si es eso lo que nos interesa, estaríamos hablando de multitargeting, es decir, la capacidad de un proyecto de compilarse y publicarse para más de un framework de forma simultánea.

Para conseguir esto, en primer lugar debemos retocar ligeramente el archivo de proyecto .csproj, sustituyendo la etiqueta <TargetFramework> por <TargetFrameworks> (ojo al plural) e introduciendo los distintos TFM separados por punto y coma:
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFrameworks>netcoreapp1.0;net461</TargetFrameworks>
</PropertyGroup>

...

</Project>
Carpeta de binarios en proyectos multi targetA partir de que configuremos el proyecto como multi target, cada compilación generará en la carpeta /bin los binarios correspondientes a cada uno de los frameworks especificados, es decir, se irán compilando al mismo tiempo todos ellos.

Además, nuestro proyecto se comportará de forma diferente en algunos aspectos. Por ejemplo, a la hora de publicarlo, obligatoriamente deberemos indicar el framework destino de dicha publicación, pues de lo contrario fallará el proceso:

Selección de target al publicar un proyecto
De la misma forma, deberemos indicar obligatoriamente el target al hacer la publicación usando la línea de comandos:

C:\MyProject>dotnet publish
Microsoft (R) Build Engine version 15.1.1012.6693
Copyright (C) Microsoft Corporation. All rights reserved.

Error: The 'Publish' target is not supported without specifying a target framework.
The current project targets multiple frameworks, please specify the framework for
the published application.


C:\MyProject>dotnet publish -f net461
Microsoft (R) Build Engine version 15.1.1012.6693
Copyright (C) Microsoft Corporation. All rights reserved.

MyProject -> c:\MyProject\bin\Debug\net461\MyProject.exe

C:\MyProject>_

Otro aspecto importante que cambiará es la gestión de dependencias. Cuando tenemos un target único y añadimos una referencia al proyecto, ésta es chequeada para comprobar que es compatible.
Por ejemplo, si en un proyecto para .NET Core intentamos añadir una referencia hacia el paquete NuGet "iTextSharp" (un componente de generación de PDF sólo disponible para .NET Framework), se producirá un error al restaurarlo:
Package iTextSharp 5.5.11 is not compatible with netcoreapp1.0 (.NETCoreApp,Version=v1.0). Package iTextSharp 5.5.11 supports: net(.NETFramework,Version=v0.0)
One or more packages are incompatible with .NETCoreApp,Version=v1.0.
Sin embargo, cuando el proyecto tiene múltiples targets podemos referenciar paquetes asociándolos a frameworks específicos. Como muestra, en el siguiente código se puede observar cómo añadimos el paquete "iTextSharp" sólo para el target "net461":
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFrameworks>netcoreapp1.0;net461</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="1.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.0.3" />
...
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net461'">
<PackageReference Include="iTextSharp" Version="5.5.11" />
</ItemGroup>
...

</Project>
Es decir, cuando estemos publicando o compilando para .NET 4.6.1, se incluirán las referencias correspondientes al paquete "iTextSharp" y podremos utilizarlo desde nuestro código.
Sin embargo, veréis que hay un problema en este enfoque. Si un proyecto es multi-target, quiere decir que la misma base de código se utilizará para generar los binarios destinados a los distintos frameworks. Y si existen dependencias hacia paquetes incompatibles, ¿cómo se gestiona esto?

Pues en primer lugar, hay que tener en cuenta que el uso desde código de cualquier biblioteca incompatible con algunos de los frameworks de destino generará un error de compilación. Por ejemplo, si incluimos una línea de código como la siguiente, donde intentamos crear un objeto propio de "iTextSharp", fallará la compilación:
var x = new iTextSharp.text.pdf.PdfDocument();
Error CS0246: The type or namespace name 'iTextSharp' could not be found (are you missing a using directive or an assembly reference?)
La verdad es que el compilador podría ser algo más explícito, pero el caso es que la compilación está fallando sólo para el target .NET Core, puesto que en este framework el paquete "iTextSharp" no ha sido incluido y, por tanto, el tipo PdfDocument no está disponible.

A nivel de IDE, Visual Studio 2017 nos ayudará a saber cuándo estamos introduciendo código no compatible con algunos de los targets. De hecho, en la propia ventana de edición del entorno existe un desplegable en el que podremos seleccionar el target a tener en cuenta durante la edición. En la siguiente captura de pantalla se muestra este desplegable, en el que tenemos actualmente seleccionado "netcoreapp1.1", por lo que vemos que se marca como error el intento de uso del espacio de nombres iTextSharp:

Desplegable de selección del target

En cambio, si en el desplegable indicamos que queremos editar en el contexto del target .NET 4.6.1 ya el error no aparecerá, aunque aún tendremos disponible información sobre la compatibilidad de estas líneas en los distintos targets:

Ayuda contextual indicando la compatibilidad de un tipo con los distintos targets
Para solucionar los problemas en compilación debemos introducir código condicional, es decir, código que sólo se introduzca en el proyecto en un target determinado. Algo parecido a lo que hicimos anteriormente al referenciar el paquete NuGet, pero utilizando la directiva #if de C# para comprobar si existen constantes como NET461 o NETCOREAPP1_1.

Por ejemplo, el siguiente bloque de código muestra un controlador MVC que podría retornar un archivo PDF o TXT dependiendo de si el target es .NET 4.6.1 (que es compatible con "iTextSharp") o no. Si el target es .NET Core, no compatible con el paquete necesario para generar PDF, proporcionamos al menos una alternativa honrosa retornando el archivo en formato de texto plano:
public IActionResult DownloadInvoiceDocument(int invoiceId)
{
var invoice = _invoiceServices.GetInvoice(invoiceId);
if (invoice == null)
{
return NotFound();
}

#if NET461
return File(TextSharpHelper.GenerateInvoicePdf(invoice), "application/pdf");
#else
return File(PlainTextHelper.GenerateInvoiceText(invoice), "text/plain");
#endif
}
...

#if NET461
public class TextSharpHelper
{
internal static string GenerateInvoicePdf(dynamic invoice)
{
// Generate PDF using iTextSharp
}
}
#endif
Ya habiendo tomado estas precauciones, el proyecto compilará para todos los targets, aunque en cada uno incluirá distintas funcionalidades.

Publicado en Variable not found.

» Leer más, comentarios, etc...

Una sinfonía en C#

Pomodoros: organización, productividad, salud, motivación, constancia.

mayo 16, 2017 01:00

Nota: este es un post no-técnico de opinión/experiencia personal.

Hace un tiempo parece que muchas de las charlas que tengo con colegas y hasta amigos terminan en el mismo lugar motivadas por diferentes factores pero digamos que casi siempre tiene el mismo origen: el día a día.

A modo de disparador voy a enumerar las principales ideas y frases que surgen de estas conversaciones.

  • No llego a terminar nada durante el día.
  • Me cuesta concentrarme con tanta interrupción.
  • Se me hace muy largo el día.
  • Termino la jornada sin ganas de hacer nada.
  • Me duele todo el cuerpo por estar sentado tanto tiempo.

Y claro todo esto esconde detrás diferentes problemáticas, algunas cosas son comunes, porque todos sabemos que en nuestra industria hay muchos cambios, que en la vida actual hay muchas interrupciones y que sufrimos un desgaste mental y físico por el tipo de tarea que hacemos y cómo la hacemos: estamos muchas horas sentados y tenemos que aplicar conocimientos, imaginación y decisiones todo el tiempo.

Pomodoro con mis ajustes

Voy a contar qué hago yo que no es nada nuevo, es una variante de la técnica del pomodoro, pero con el agregado de años de hacerlo e ir detectando qué es mejor para mí:

Básicamente, durante 25’ me focalizo en una tarea y después tomo un descanso de 5’, y cuando digo me concentro y después descanso hago varias cosas para que este tiempo sea de máximo provecho:

  • Apagar notificaciones: de todo tipo, Skype, Whatsapp, No mirar los mails, no mirar Facebook, nada; todas las interrupciones que pueden esperar 25’ se deben evitar.
  • Tener bien claro qué voy a hacer en esos minutos: invertir un poco de tiempo (tal vez un pomodoro) en organizar que voy a hacer durante esos 25’ para que sean provechosos.
  • Concentrarse en una única cosa: Si estamos programando por ejemplo puede que haciendo TDD u otra cosa vayan surgiendo otras, por ejemplo estamos haciendo TDD y nos damos cuenta de un caso de test que no tuvimos en cuenta, entonces lo anotamos de alguna manera: escribimos el nombre del caso, lo anotamos en un archivo de texto, en un papel, lo que sea, pero no nos desenfocamos de lo que estamos haciendo ahora mismo.
  • Tener todas las herramientas / información para lo que tenemos que hacer.
  • Ir por incrementos: si lo que vamos a hacer es complejo, apuntamos a algo que podemos terminar en 25’ una iteración, una primera versión (tal vez código no tan eficiente y refactorizar durante otro pomodoro)
  • No continuar más de 30’: si estamos muy concentrados con algo y nos pasamos de los 25’ lo demos ahí si podemos o intentamos tener una versión lo más rápido posible pero no nos excedemos porque estamos entusiasmados porque todo fluye, esto no hace más que cansarnos para los pomodoros posteriores.
  • Levantarse de la silla durante los 5’ de descanso: levantarse y caminar, desconectarse de lo que estamos haciendo, yo a veces todo un poco el piano o la guitarra, tiene que se un descanso físico y mental.
  • Aprovechar para estirar el cuerpo: esto es un agregado mío a la técnica, pero nos va a hacer muy bien: durante uno o dos minutos hacemos algunos ejercicios para relajar la espalda, estirar las piernas y demás.
  • Nunca, pero nunca, salta un descanso: por motivos físicos y mentales, todos saemos que trabajar de más no es bueno y menos sostenible, esto es lo mismo, tenemos que confiar en este proceso.

Yo no creo en ser tan estrictos con las reglas de casi nada (no entremos en detalles) pero tal vez para vos no funcionen 25’ sino 20’ y está perfecto, después uno irá encontrando su tiempo, lo importante es no excederse de los 30’ según mi experiencia.

Prioridades

Como en todo proceso ágil, es bueno comenzar atacando lo más riesgoso y que más incertidumbre nos cause, por supuesto utilizando prioridades y comenzando por lo más prioritario primero, de esta manera disminuimos el riesgo, la incertidumbre y vamos aprendiendo en el camino.

Pomodoros de diferentes cosas

Es buena idea utilizar pomodoros para organizar o reorganizar el trabajo, al prinicipio o mitad del día, o cuando sea, pero la idea general es la misma: Timebox y foco. Podemos hacer pomodoros de cualquier cosa, siempre intentando explotar sus principios.

Para ir mejorando

Al igual que todo proceso es mejor si es iterativo y lo vamos mejorando con el tiempo, aunque parezca poco si durante una jornada laboral de 8 horas hago 11 o 12 pomodoros considero que fue un día excelente, y van a notar que aplicando la técnica esto puede significar un progreso gigante aunque parezca que perdimos horas de trabajo.

Motivación

En mi caso una vez que fui encontrando la mejor forma para mí de aplicar estos conceptos mejoró mucho la motivación, no voy a descubrir nada si digo que trabajar alcanzando “pequeños triunfos” es mejor que trabajar todo el día para esperar el logro final, como se demuestra en el desafío del malvavisco.

Constancia

En mi caso esto me permite mantener una constancia, porque me siento más contento con la marcha de las cosas, más enfocado y obtengo resultados que me entusiasman en lugar de ver un gran resultado solamente al final de un gran esfuerzo.

No solo en desarrollo de software

Yo he aplicado estos mismos principios para hacer cosas bien diferentes al desarrollo de software, como preparar una charla, estudiar algo nuevo, practicar tocar el bajo y demás.

Dejo algunos links

Nos leemos

» Leer más, comentarios, etc...

Adrianistán

Anrokku, un videojuego tipo puzzle

mayo 15, 2017 08:18

Anrokku es un juego de puzles que he programado estas semanas. Las reglas son simples, somos una ambulancia y tenemos que salir del parking debido a una emergencia. Desafortunadamente el parking es un caos y los coches bloquean la salida. Tu labor es ir moviendo los coches para lograr que la ambulancia salga del parking. Y cuantos menos movimientos hagas mejor.

En el menú principal podremos seleccionar a cuál de los 20 niveles queremos jugar. No podremos jugar a todos a la vez, es necesario habernos pasado los niveles anteriores para desbloquear el siguiente.

Ya en el juego tenemos que ir arrastrando los coches con el ratón para que la ambulancia pueda irse por la derecha. El juego está programando en Python 2.7 usando GTK. El renderizado está hecho en un GtkDrawingArea donde he usado Cairo. ¿Quiéres jugar? El juego completo es gratuito y open source bajo la liencia MIT en GitHub. No obstante, puedes descargar el archivo ZIP con el juego desde este enlace.

Descargar Anrokku

Después de descargar y descomprimir el archivo. Ejecuta el fichero main.py haciendo doble click o desde la terminal:

python2 main.py

¡Quiero ver muchas pantallas como esta!

 El juego almacena los récords obtenidos en cada nivel. Puede ser interesante repetir los niveles para hacerlo en el menor número posible de movimientos. En el primer nivel he conseguido ganar en 32 movimientos, ¿alguien se atreve a superarme?

La entrada Anrokku, un videojuego tipo puzzle aparece primero en Blog - Adrianistan.eu.

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 282

mayo 15, 2017 06:55

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

.NET/.NET Core

ASP.NET/ASP.NET Core

Azure / Cloud

Conceptos/Patrones/Buenas prácticas

Data

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Cross-platform

Otros

Y para terminar, una pequeña reflexión de la mano de xkcd… ¿a veces somos algo idiotas? ¿o quizás demasiadas veces? ;D

I'm An Idiot

Publicado en Variable not found

» Leer más, comentarios, etc...

Koalite

Soluciones habitacionales para aplicaciones multitenant

mayo 15, 2017 04:06

Hoy en día comercializar el software en forma de servicio, con cuotas recurrentes en lugar de una licencia perpetua, actualizaciones periódicas (si no continuas) y gestión externalizada, es cada vez más habitual. Los motivos son varios, desde el claro atractivo de cobrar más por (más o menos) lo mismo, hasta el mundo de posibilidades que nos ofrece la tan manida nube.

Cuando se trata de diseñar una aplicación preparada para este tipo de comercialización, uno de los puntos que hay que tener en cuenta es la forma en que vamos a gestionar los distintos clientes de nuestra aplicación. Si hablamos de software para empresas, nuestros clientes serán empresas con uno o más usuarios, y cada una de ellas trabajará con su propia información.

Existen varias formas de gestionar esto dependiendo de qué recursos estemos dispuestos a compartir entre cada una de nuestros clientes (tenants) y, como siempre, cada una de ellas tiene sus propias características que la hacen más o menos atractiva dependiendo del contexto.

OJO: aviso de antemano que mi experiencia en este ámbito es terriblemente limitada y se reduce a alguna aplicación pequeña. Mi objetivo es intentar poner en claro mis pensamientos y, si con un poco de suerte, consigo que en los comentarios me corrijáis y déis más ideas, estupendo.

Independencia total

unifamiliar

Una alternativa que, a priori, parece bastante sencilla, al menos desde el punto de vista de desarrollo, es mantener completamente aislados a nuestros clientes unos de otros. Para cada uno de ellos desplegaremos una instancia de nuestra aplicación, incluyendo servidor, base de datos, etc.

Sería equivalente a construir viviendas unifamiliares para nuestros clientes. Todos tienen la misma estructura, pero son virtualmente independientes. Probablemente necesitemos construir algo de infraestructura común, por ejemplo, para el acceso, pero por lo demás nuestro sistema prácticamente será igual que si tuvieramos un sólo cliente, lo que simplifica consideramente el desarrollo.

Además, este enfoque tiene otras ventajas, como que podríamos llegar a personalizar la aplicación para cada cliente si fuera necesario, creando distintas variantes de la misma sin tener que pensar si las modificaciones que hacemos para un cliente afectan a los demás. No hace falta pegarse con los vecinos para decidir si ponemos un ascensor o no, cada vivienda es independiente y puede hacer lo que necesite.

La gestión de la información es fácil: cada cliente tendrá su propia base de datos aislada, lo que nos permitirá ofrecerle backups propios sin dificultad o eliminar su información cuando deje de ser cliente nuestro y cumplir con los requisitos legales que sean necesarios.

Puesto que son despliegues independientes, los problemas de un tenant no deberían afectar al resto. Por desgracia, en la vida real más que chalets independientes tendremos chalets pareados, porque estaremos tendremos máquinas virtuales o contenedores que comparten máquina física, y es posible que algo nos molesten los ruidos del vecino.

En la parte negativa, con esta idea tendremos unos costes operacionales mayores porque necesitaremos mantener en producción más instancias de servidores y bases de datos. Los costes de infraestructura también crecerán porque es más complicado aprovechar bien los recursos, y es probable que tengamos máquinas (virtuales o físicas) infrautilizadas.

Otro problema es que si dejamos que las versiones desplegadas para cada tenant diverjan en exceso, al final ya no tenemos un producto, sino un produyecto y nos alejamos de las ventajas de tener algo paquetizado que podamos vender de forma sencilla tantas veces como queramos.

En realidad, esta opción no deja de ser una forma de resolver el problema evitándolo. No estamos construyendo una aplicación multitenant; tan sólo estamos desplegando muchas aplicaciones single tenant. A veces es una opción perfectamente válida y puede ser un primer paso hacia otras alternativas.

Independencia de datos

pau

El siguiente paso podría ser mantener parte de la infraestructura común, pero separar los datos de cada tenant. Podríamos tener un mismo servidor web (o un pool de servidores web, dependiendo de nuestra arquitectura) compartidos entre todos los tenants, y luego mantener bases de datos completamente independientes para cada tenant.

Sería similar a una vivir en una comunidad de vecinos. Una parte importante de la infraestructura es común (acceso a las viviendas, instalación eléctrica, fontanería, ascensores, etc)., pero luego cada uno cuenta con su propia casa y (hasta cierto punto), hace en ella lo que quiere.

En este escenario podemos aprovechar mejor la parte de frontend (los servidores web), y escalar el almacenamiento de datos según vayan apareciendo nuevos tenant. A nivel de desarrollo es algo más complicado que antes, porque necesitaremos asegurarnos de que cada tenant accede a la base de datos adecuada y que el resto de información dependiente del tenant (como ficheros de configuración) se trata correctamente. Al final, es relativamente sencillo mover casi toda es configuración a la base de datos, por lo que si resolvemos esa parte, el resto viene rodado.

Mantener los datos independizados mantiene las ventajas del enfoque anterior, pudiendo proporcionar a cada tenant copias de seguridad o acceso a sus datos (y sólo a sus datos) fácilmente y gestionarlos de forma acorde a la normativa legal que toque de cara a borrados y demás.

Al haber aumentado la parte compartida entre tenants, ya no es tan sencillo hacer modificaciones específicas para cada uno de ellos. Siguiendo con el ejemplo de la comunidad de vecinos, si queremos cambiar el modelo de ascensor, el horario de la piscina, las lámparas del descansillo o incluso el aspecto de los buzones, será necesario hacerlo de forma coordinada con el resto de vecinos.

También se incrementa la probabilidad de que problemas de un tenant afecten a otros. Si un tenant realiza una operación que introduce mucha carga en el frontend, el resto de tenants podrían verse afectados. Igual que en una comunidad de vecinos, si el de arriba monta una fiesta te acabarás enterando.

Este acoplamiento entre tenants hace que corramos el riesgo de acabar teniendo una aplicación excesivamente compleja de configurar y/o extender por la cantidad de funcionalidades solapadas que puede ser necesario soportar para dar cabida a los distintos requisitos de cada tenant y las interacciones entre ellas.

La carga operacional y los costes de infraestructura se reducen porque ya no necesitamos controlar instalaciones completas para cada tenant, pero seguimos necesitando una buena estrategia para gestionar las distintas bases de datos, mantener sus esquemas, copias de seguridad, planes de mantenimiento, etc.

Sistema compartido

shared

Si en el enfoque anterior unifícabamos la parte de frontend, el siguiente paso podría ser unificar también la parte de almacenamiento de información. Podríamos verlo como un piso de estudiantes, en el que ya no sólo compartimos la infraestructura general, sino que también tenemos que compartir cosas más básicas como la nevera o el baño.

Igual que en un piso compartido hace falta idenficar de quién es cada cosa y es frecuente ver notas en la comida de la nevera, cuando tenemos una aplicación multitenant en la que compartimos el sistema de almacenamiento habrá que poder diferenciar de quién es cada dato.

Existen varias formas de hacerlo. Si la base de datos lo soporta, podríamos utilizar un esquema diferente para cada tenant, lo que es bastante limpio y relativamente fácil de implementar en la aplicación. Siguiendo con el símil habitacional, sería parecido a repartir los estantes de la nevera. Otra opción es añadir en cada registro de la base de datos (o documento, o lo que sea que use la base de datos) un indicador del tenant al que pertenece. La equivalencia sería poner un post-it en cada cosa que hay en la nevera. Esto requiere un trabajo mucho mayor a nivel de aplicación y hay que tener especial cuidado para evitar comerse las cosas de otro fugas de información entre tenants.

Una ventaja directa de este sistema es que a nivel operacional sólo tenemos que mantener una única aplicación con su(s) base(s) de datos. Esto simplifica la parte de despliegue de nuevas versiones, monitorización, copias de seguridad, etc. Además, es más fácil optimizar los recursos empleados y reducir los costes de infraestructura. Sale más barato compartir piso que vivir en un chalet.

Si queremos escalarlo puede ser más complicado que con las opciones anteriores, pero con un poco de sentido común, si mantenemos el frontend sin estado, es relativamente fácil escalar añadiendo más máquinas, y podemos recurrir a técnicas de sharding para repartir los tenants en varias bases de datos (sin necesidad de ir a una base de datos por tenant), lo que nos debería permitir llegar bastante lejos.

Entre los problemas, además de tener el mismo acoplamiento a nivel de código que en el caso anterior, tenemos el acomplamiento a nivel de base de datos, por lo que es más fácil que los problemas de un tenant afecten a otro. Ya no sólo es que puedan sobrecargar el frontend, también pueden sobrecargar la parte de almacenamiento, o incluso dependiendo de lo mal que lo hayamos hecho, saturarla superando el máximo almacenamiento permitido y tirando abajo todo el sistema. Aquí ya no es que el vecino de arriba monte una fiesta, es que la fiesta está en tu salón. Todo esto es controlable, pero requiere un esfuerzo adicional. 

Una parte que se complica más con este esquema es poder ofrecer a cada tenant copias de seguridad o acceso directo a su almacenamiento de datos. Necesitaremos un sistema que nos permita copiar, borrar y gestionar partes de la base de datos por separado. Antes lo teníamos “gratis” con las herramientas propias de la base de datos, y ahora nos tocará correr a nosotros con ese esfuerzo.

Resumen

Seguro que existen muchas más alternativas para desarrollar aplicaciones multitenant, y además estoy convencido de que cada caso real tiene un montón de peculiaridades que hacen que deba ser analizado por separado.

Aun así, creo que los ejes en los que se mueven las distintas soluciones son los habituales en el desarrollo de desarollo: coste de desarrollo, coste de mantenimiento, flexibilidad, etc.

Cuando más desacoplemos los diferentes tenant de la aplicación menores serán los costes de desarrollo y más flexibilidad tendremos para gestionar, si fuera necesario, cada tenant como un proyecto diferente. Si tendemos a unificarlos, podremos minimizar los costes de explotación, lo que muchas veces puede ser determinante en este tipo de desarrollos.

Posts relacionados:

  1. Diseñando un router para aplicaciones SPA
  2. Logs para aplicaciones javascript con persistent-log

» Leer más, comentarios, etc...

Blog Bitix

Luces navideñas con la Raspberry Pi y Java

mayo 14, 2017 09:00

Con diferentes sensores y dispositivos de salida de electrónica se pueden realizar proyectos muy interesantes. En el siguiente usaré múltiples diodos LED que se encenderán y apagarán de forma aleatoria cada cierto tiempo. El resultado será muy vistoso y lo utilizaré cuando lleguen las fechas como luces navideñas.

Raspberry Pi
Java

Como muestra de lo que se puede hacer con la Raspberry Pi usando los pines GPIO haré un ejemplo que consistirá en múltiples diodos LED de diferentes colores enciendan y apaguen simulando una especie de luces navideñas. Como yo tengo la Raspbperry Pi 1 B con 26 pines de los cuales solo 17 son GPIO podré usar hasta 17 diodos LED, aunque solo usaré 15. En el kit de iniciación a la electrónica para la Raspberry Pi viene incluidos 24 diodos LED de diferentes colores 6 blancos, 6 rojos, 6 amarillos y 6 verdes, también es necesario una resistencia por cada diodo de unos 200 ohmios de los cuales en el kit se incluyen 20 de este valor.

Aunque con muchos más LED el ejemplo no es más complicado que el ejemplo que ya mostré de encender y apagar un diodo LED. Usaré diodos de diferentes colores y dispuestos de forma aleatoria para darle un aspecto desordenado, para darle un aspecto más caótico los LEDs se encenderán y apagarán de forma aleatoria. Usaré el lenguaje de programación Java y la librería de alto nivel diozero para controlar el encendido y apagado de los diodos.

Esta es la foto del cableado usando múltiples cables macho-macho para conectar los pines con el polo positivo de los diodos pasando por la resistencia y también múltiples cables para conectar el polo negativo del diodo con tierra. Usando una placa breadboard para realizar las conexiones sin soldadura y una placa de extensión wiringPi para conectar la Raspberry Pi con la placa breadboard con un cable de 26 pines en mi caso por el modelo que tengo de RPi este es el aspecto de cableado.

Cableado de las luces LED del árbol de navidad

Cada cierto tiempo los diodos cambian de estado, algunos se encenderán, otros se apagarán y otros seguirán en el estado que estaban. Para ello generaré un booleano aleatorio para cada uno de los diodos que determinará si debe estar encendido o apagado. Este es el programa Java junto con la parte relevante del archivo Gradle para compilar y construir el ejemplo y el comando que uso para ejecutarlo.

Esta aplicación para la Raspberry Pi queda bastante vistosa y no es muy complicado de realizar a pesar del del lío de cables que resulta. Este es un vídeo de su funcionamiento.

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando el comando ./gradlew executeChristmasTree.

» Leer más, comentarios, etc...

Blog Bitix

Controlar un servomotor con la Raspberry Pi y Java

mayo 13, 2017 09:40

Raspberry Pi
Java

Otro de los elementos que incluye el kit de iniciación a la Raspberry Pi es un servomotor, en concreto uno del modelo SG90. En la especificación del servomotor SG90 está detallado cual es el código de colores de los cables. Rojo para la corriente de 5V, marrón para tierra y naranja para el pin PWM con el que se controlará el servo motor, el diodo led es simplemente para saber que cuando se enciende el programa Java se ha iniciado. La Raspberry Pi tiene algunos pines con soporte hardware para realizar PWM.

Un servomotor es un elemento distinto de un motor, un motor usa dos cables uno para mover el motor hacia adelante y otro cable para mover el motor hacia atrás. Los servomotores además de utilizar un único cable para controlarlo su funcionalidad es distinta usándose para posicionar el motor en un determinado ángulo que en el caso del SG90 tiene un ángulo de funcionamiento de 180º. Además el servomotor es más complejo, como se explica en el siguiente artículo de título ¿Cual es la diferencia entre un motor DC y servo motor? el servomotor se compone de varios elementos empaquetados como una pieza. Se compone de un motor DC normal, una unidad de reducción, un sensor de posicionamiento y un circuito de control.

Servomotor y cableado

La función del servomotor es recibir la señal de control y aplicar corriente al motor hasta que que esté en la posición indicada por la señal. Un servomotor no rota libremente sino que como he comentado en el caso del SG90 tiene un ángulo de funcionamiento de entre 0º y 180º. La señal de control es un pulso de anchura modulada o PWM.

Usando la librería Diozero es sencillo controlar un servomotor a través de la clase Servo. El constructor recibe tres datos el pin de la Raspberry Pi que controlará el servomotor, según la nomenclatura Broadcom que usa la librería Diozero, la frecuencia del pulso PWD que sirve para controlar la velocidad de rotación y finalmente la posición inicial a establecer. Con el método pulseWidthMs y un rango de un valor float entre 0.6 y 2.4 controlaremos la posición o ángulo del servomotor.

El siguiente programa Java cambia en un bucle la posición del servo desde la posición mínima a la máxima. En él he utilizado el pin 18 que en la Raspberry Pi 1 soporta PWD, en las versiones 2 y 3 podríamos haber usado los pines 18 o 19.

Aunque he conseguido hacer funcionar el servomotor con este programa no ha sido exento de problemas. Y es que cuando el programa finaliza la Raspberry Pi se me bloquea o se pierde la conectividad de red. No se si por algún bug en la librería Diozero o alguna incompatibilidad con la Raspberry Pi 1 B, quizá en otro modelo de la Raspberry Pi no dé los problemas que a mi me da.

En otros artículos de la serie puedes consultar cómo usar otros elementos de kit con Java y la Raspberry Pi.

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando el comando ./gradlew executeServomotor.

» Leer más, comentarios, etc...

Blog Bitix

Descargar e instalar Windows 10 paso a paso desde cero

mayo 13, 2017 09:35

Un virus, el bloatware preinstalado en muchos portátiles o tras instalar y desinstalar programas en Windows puede ocasionar que el equipo sea lento, se muestren mensajes de error o un virus cifre los archivos personales. En estos casos una solución habitual sencilla, rápida y fiable de volver a usar con normalidad el equipo es reinstalar Windows 10 desde cero. No es complicado pero para un usuario con pocos conocimientos de informática no es una tarea sencilla. En este artículo explicaré como instalar paso a paso y desde cero el sistema operativo Windows 10.

Microsoft
Windows 10

Prácticamente la totalidad de portátiles que se venden en las grandes superficies comerciales más conocidas están con el sistema operativo Windows preinstalado. Pero los fabricantes con la intención dotar de más capacidades y funcionalidades que las que incorpora Windows instalan numerosos programas que conforman el conocido bloatware que en muchas ocasiones hacen que un equipo completamente nuevo sea más lento de lo normal al iniciar el sistema, al arrancar programas o trabajar con ellos. Entre los programas que suelen preinstalar los fabricantes están los antivirus que al cabo de un tiempo se desactivan ya que suelen ser versiones de evaluación pudiendo dejar al equipo desprotegido ante virus y software malicioso, Windows 10 ya incorpora uno, Windows Defender, y para la mayoría de usuarios es suficiente por su efectividad aceptable. Otros programas que los fabricantes suelen instalar son reproductores de vídeo o software multimedia en la mayoría de casos innecesario ya que Windows de por si ya incorpora las capacidades de trabajar con archivos multimedia como fotografías o vídeos. También puede darse el caso que tras una actualización o la instalación de un programa el equipo empiece a presentar fallos.

En los casos anteriores realizar una reinstalación de Windows desde cero es necesaria. Muchos usuarios no tienen conocimientos avanzados de tecnología o informática y no conocen los pasos para realizar una reinstalación. En este artículo explicaré detalladamente, paso a paso y desde cero cuales son los pasos que hay que realizar para instalar Windows 10.

Requisitos mínimos

Lo primero es conocer que Windows 10 para funcionar correctamente posee unos requisitos mínimos para el equipo en el que vaya a ser instalado, fue comercializado en julio del 2015 y cualquier equipo posterior a esa fecha ya cumplirá con los requisitos mínimos y también los equipos que cumpliesen con los de Windows 7 o viniesen preinstalados con esta versión anterior. En la página de Especificaciones y requisitos del sistema para Windows están detalladas una buena cantidad de notas informativas y los requerimientos que son los siguientes:

  • Procesador: Un procesador a 1 GHz o más rápido o SoC
  • RAM: 1 gigabyte (GiB) para 32 bits o 2 GB para 64 bits
  • Espacio en disco duro: 16 GB para un SO de 32 bits o 20 GB para un SO de 64 bits
  • Tarjeta gráfica: DirectX 9 o posterior con un controlador WDDM 1.0
  • Pantalla: 800 x 600

Estos son los requisitos básicos, los recomendables para una buena experiencia de uso son disponer de 4 GiB de memoria y con esta memoria el siguiente aspecto con el que más se nota una mejora es disponer de un disco duro de estado sólido o SSD en vez de mecánico ya que son varias magnitudes más rápidos tanto en la lectura como en la escritura.

Cualquier equipo nuevo cumple con estos requisitos pero quizá algunos no posean disco duro SSD, estos discos son más caros y ofrecen menos capacidad aunque ya se han abaratado y son bastante asequibles y su capacidad a partir de los 128 GiB o 256 GiB son suficientes para muchos usuarios. Pagar algo más por un equipo con un disco SSD es una buena decisión, un equipo con disco mecánico puede tardar 1 o 2 minutos en iniciarse, uno con un SSD menos de 10 segundos lo que es solo un ejemplo entre la diferencia entre unos y otros.

Copia de seguridad

Una vez que sabes que el equipo cumple con los requisitos mínimos hay que hacer una copia de seguridad de los documentos, fotos y demás archivos personales que posea el equipo y quieras conservar en un disco duro o memoria USB externo, si son muchos los datos en vez de copiar y pegar con el explorador de archivos puedes hacer la copia de seguridad con el programa FreeFileSync y restaurar los datos también con el mismo programa una vez reinstalado Windows.

Realizar copia de seguridad con FreeFileSync

Creación del medio de instalación

En versiones anteriores de Windows este debía buscarse en las redes de compartición de archivos o P2P como torrent. Con Windows 10 Microsoft sabiamente para evitar problemas de seguridad proporciona la imagen ISO o una herramienta de creación del medio USB desde su propia página. Para descargar la imagen ISO de Windows hay que seleccionar la edición a descargar (en el momento de escribir este artículo la última es la Creators Update) y el idioma.

Según la actualización de Windows descargada las capturas de pantalla o pasos variarán pero serán similares en gran parte. En este artículo he utilizado la actualización Creators Update, la anterior era Anniversary Update y la anterior la versión original de Windows 10. Cualquier equipo de la última década ya incorpora un procesador de 64 bits, que el procesador sea de 64 bits le permite usar tamaños de memoria superiores a 4 GiB.

Accediendo a la página de descarga de Windows 10 desde un sistema con Windows 7, Windows 8.1 o Windows 10 se mostrará la opción de descargar la herramienta de creación de medios o Media Creation Tool. Descargada y ejecutada la herramienta realiza la descarga de Windows 10 y la creación de medio ya sea un DVD o memoria USB. En el caso de la memoria USB esta deberá tener una capacidad de al menos 8 GiB y todos los datos que posea se perderán con lo que su datos en su caso deberán ser salvaguardados en otra unidad externa.

Para realizar la instalación de Windows 10 es más recomendable usar una memoria USB con el programa Media Creation Tool ya que es más rápida que utilizar un disco DVD ya en desuso para los que algunos sistemas ya ni siquiera incorporan su lector.

Creación del medio de instalación

Inicio instalación de Window 10

Una vez está listo el medio de instalación de Windows 10 en forma de memoria USB o DVD con el equipo apagado y el medio de instalación conectado a un puerto USB o insertado en el lector de DVD hay que iniciarlo para que arranque desde el medio de instalación. Según el fabricante iniciar el equipo desde el medio de instalación varía ligeramente pero suele emplearse la pulsación de una tecla cuando el equipo se inicia que suele ser la tecla F2, F8, F10, F12 o la tecla Escape que permite seleccionar la unidad desde la que se inicia el equipo donde hay que elegir la memoria USB o DVD. Puede ser que la tecla de acceso a la BIOS UEFI donde también se podrá seleccionar el orden de arranque de las unidades que también varía según el fabricante, la BIOS UEFI contiene parámetros importante de configuración del equipo con lo que hay que tener precaución en las cosas que se modifican en ellas por lo que si no estás seguro de los cambios que estás realizando no los guardes, por suerte las últimas versiones de las BIOS UEFI son más intuitivas y con interfaces gráficas más fáciles de usar.

Según el fabricante e incluso modelos de la misma fabricante la tecla de acceso para iniciar desde el medio de instalación varía:

  • Acer: F2 o Delete
  • Asus: F2 o F10
  • Dell: F2, F1, Delete, F12 o F3
  • HP: F10 o Esc
  • Lenovo: F1 o F2
  • Sony: F2, F3, F1 o tecla assist
  • Toshiba: F2, F1, Esc

En las siguientes páginas puedes encontrar varias posibles teclas para entrar en la BIOS y cambiar la unidad de inicio del sistema según la marca, I, II y III.

Puede ser el caso de que cuando se inicia el equipo muestre un mensaje con la tecla que hay que pulsar si hay que probar hasta dar con ella. Después de pulsar la tecla de encendido poco después o según se muestra un logotipo es cuando hay que pulsar la tecla.

Asistente de instalación de Windows 10

Uno de los éxitos de Windows 10 es que la instalación ofrece un asistente con el que después de completar varios pasos y pulsaciones en botones Siguiente el sistema queda instalado y listo para usarse. La instalación se completa en menos de una hora.

Entre los pasos están la selección del idioma, la versión del sistema Home o Pro (la primera es suficiente), la lectura de de los términos de la licencia de uso que poca gente se lee completamente por su extensión y su jerga legal poco comprensible. Si el equipo tiene una licencia se ofrecerá la posibilidad de introducir la clave del producto para activar Windows, si no la tiene es posible omitir este paso pulsando la opción No tengo clave de producto y usar Windows sin limitaciones durante un tiempo, pasado un tiempo en cualquier caso las limitaciones son muy leves y Windows 10 es usable con normalidad.

Es recomendable la instalación Personalizada: instalar solo Windows y no conservar archivos y configuraciones anteriores para evitar problemas o heredarlos del sistema anterior. También es recomendable eliminar todas las particiones del disco y dejar que Windows cree las necesarias.

Instalación de Windows 10

Tras unos pasos donde se mostrará el progreso de instalación y algún reinicio automático el sistema se inicia con un asistente de configuración para personalizar el sistema.

Configuración básica

Después de instalar Windows este ofrece un nuevo asistente donde se personalizan algunas cosas adicionales del sistema. Algunas opciones a seleccionar en estos pasos antes de empezar a usar Windows 10 son:

  • La región o país del usuario.
  • La distribución o disposición de las teclas del teclado.
  • El usuario de inicio de sesión ya sea con una cuenta de Microsoft o con una cuenta sin conexión y la contraseña.
  • Si se desea usar Cortana como asistente personal.
  • Algunas opciones de privacidad que son recomendables desactivar para que Windows no recopile información de nuestro dispositivo aunque sean datos anónimos.
Configuración inicial de Windows 10

Usando Windows

Si el equipo ya tenía licencia de de Windows y estaba activado seguramente Windows 10 ya lo reconozca como activado. También es muy probable que Windows 10 sea capaz de reconocer automáticamente todo el hardware que posea en el equipo incluyendo la tarjeta gráfica pasa usar la máxima resolución que ofrezca la pantalla.

Llegado a este punto Windows 10 ya se puede empezar a usar y quizá instalar el software básico que vayas a utilizar como un paquete ofimático ya sea Microsoft Office o alguna de las mejores 3 alternativas a Microsoft Office, un navegador web como Firefox o Chrome con el complemento para bloquear publicidad AdBlockPlus en vez de usar Microsoft Edge que está incorporado por defecto.

Aún sin licencia y sin activar Windows 10 es perfectamente usable, quizá al cabo de un tiempo no puedas cambiar algunas opciones de personalización como el fondo del escritorio o temas de las ventanas pero nada importante que impida usarlo. Y en cualquier caso Windows 10 y Office 2016 siguen siendo tan fáciles de usar sin licencia como siempre.

Windows 10

Alternativa a Windows con distribuciones GNU/Linux

Debes conocer que Windows no es la única opción de sistema operativo que puedes instalar, si quieres puedes probar alguna de las distribuciones GNU/Linux como alternativa a Windows y descubrir el mundo del software libre que respeta tus derechos y no te los quita como el software privativo, puedes leer el artículo Elegir una distribución GNU/Linux según el usuario o equipo e instalar Ubuntu paso a paso desde cero.

Las siguientes son unas capturas de pantalla de varias de las distribuciones GNU/Linux más famosas.

Ubuntu y elementaryOS
Fedora y openSUSE

» Leer más, comentarios, etc...

Blog Bitix

Descargar e instalar la distribución Ubuntu de GNU/Linux paso a paso desde cero

mayo 13, 2017 07:00

Pasar de usar Windows a usar una distribución GNU/Linux es un paso difícil para muchos usuarios, algunos usuarios desconocen incluso que tienen la posibilidad de usar un sistema operativo alternativo a Windows. O si lo conocen pueden creer erróneamente que instalar una distribución GNU/Linux es muy complicado… sabiendo algunas casas por lo demás es tan sencillo instalar como el sistema operativo Windows ya que muchas distribuciones incluyen una interfaz gráfica en su instalador y el proceso consiste en responder unas pocas preguntas, introducir algunos datos y pulsar varios botones siguiente.

Ubuntu
Linux
GNU

Quizá hayas oído hablar de Linux o GNU/Linux como alternativa al sistema operativo de Microsoft Windows y sientes curiosidad por probarlo y adentrarte con ello en el mundo del software libre. Si estás leyendo esta guía y te es necesaria para instalar una de las muchas distribuciones de GNU/Linux entiendo que necesitas ayuda para saber como instalarlo desde cero, paso a paso y empezando desde lo más básico.

En GNU/Linux para cada tarea que un usuario quiera realizar hay múltiples opciones entre las que elegir, desde tareas ofimáticas como LibreOffice, navegadores web como Firefox o Chrome, mensajería instantánea como Empathy, correo electrónico como Evolution, Thunderbird o Geary, reproductores de música o vídeo como VLC, visor de imágenes y archivos PDF, edición fotográfica como GIMP, edición de vídeo como OpenShot, algunos juegos destacables, … en todos los casos hay un programa de software libre por el que no hay que pagar una licencia ni buscar cracks para activar el software que son fuente de virus y problemas de seguridad. Y ya desde hace mucho tiempo en GNU/Linux el hardware es reconocido y usable en su mayor parte desde el primer momento incluyendo la tarjeta gráfica, sonido, red, bluetooth, wifi, HDMI, USB, … aunque alguno puede necesitar instalar sus controladores de dispositivo.

Debes saber es en GNU/Linux hay muchas versiones o distribuciones, muchas desarrolladas por personas sin ánimo de lucro que se agrupan formando comunidades y otras que tienen el soporte de una empresa pero que a los usuarios les ofrece la distribución sin ningún coste ni necesidad de adquirir licencias. Una distribución está formada por el conjunto de programas de software o paquetes, repositorios de paquetes y gestor de paquetes. Hay muchas distribuciones, y muchas son cientos, pero no más de 10 con una cuota de uso dentro de las distros significativa.

El paso de Windows a GNU/Linux significa usar un nuevo entorno y es algo que muchos de los usuarios que hoy somos de GNU/Linux hemos dado en algún momento, yo empecé por pasar De Windows a Arch Linux y aún me mantengo De Arch Linux a Arch Linux. GNU/Linux tiene sus puntos fuertes y algunos para los usuarios de escritorio menos fuertes, principalmente debido a no ser el sistema mayoritario los fabricantes tienen más en cuenta a Windows cuando lanzan un nuevo producto, en el caso de los juegos triple AAA o la excesiva fragmentación por la cantidad de opciones. En cualquier caso muchas distribuciones GNU/Linux son tan fáciles de usar como Windows o macOS y tan o más capaces que estos.

Lo primero que debes hacer es decidir la distribución que quieres instalar, según tus preferencias y necesidades. Para los usuarios que van a tener su primer contacto con GNU/Linux algunas de las recomendadas son Ubuntu o elementaryOS. En este artículo explicaré como instalar Ubuntu en su versión 16.04 LTS, los pasos son similares para elementaryOS ya que es una distribución que se basa en Ubuntu.

Las versiones LTS de Ubuntu tienen un soporte de largo plazo de 5 años para corrección de errores y fallos de seguridad y se publican cada dos años siendo la siguiente LTS la 18.04 que se publicará en marzo del año 2018. Salvo que estés afectado por versionitis y quieras tener las últimas versiones de los programas la versión LTS es más recomendable.

Requisitos mínimos

Los requisitos mínimos de Ubuntu son bastante bajos para cualquier sistema de unos pocos años. Aunque en la memoria es recomendable tener al menos 2 GiB o incluso 4 GiB.

  • Procesador de 700 MHz (Intel Celeron o mejor)
  • Memoria del sistema 512 MiB RAM
  • 5 GB de espacio de almacenamiento (o memoria USB, tarjeta de memoria o unidad externa)
  • Gráficos con resolución de al menos 1024x768
  • Unidad CD/DVD o puerto USB
  • Acceso a internet es recomendable

Copia de seguridad

Al instalar Ubuntu todos los datos que tuviese el equipo se perderán por lo que si quieres conservarlos debes copiarlos previamente a un disco duro externo o memoria USB de la capacidad que necesiten tus archivos, una vez finalizada la instalación de Ubuntu puedes recuperarlos y copiarlos al equipo de nuevo.

Descarga de Ubuntu

Antes de iniciar la instalación hay que descargar la imágen ISO de la versión de Ubuntu que queramos instalar. En la página oficial de Ubuntu se puede descargar de forma directa con el navegador o vía P2P en la red de compartición de archivos torrent. Ubuntu a su vez proporciona varias versiones de su distribución donde varía el entorno de escritorio que también debes elegir según tus preferencias, hay varias posibilidades Unitiy (que en la versión 18.04 será sustituida por GNOME), GNOME y KDE aunque recomiendo una de las dos últimas. Cualquiera de ellas con un aspecto gráfico muy cuidado, intuitivas y fáciles de usar. La opción más similar al entorno de escritorio de Windows es KDE con la que te encontrarás bastante cómodo al usarla si provienes de Windows.

Creación del medio de instalación

Para una mayor velocidad de instalación es mejor usar una memoria USB de al menos 8 GiB de capacidad en vez un CD o DVD que son más lentos y algunos equipos nuevos ya ni siquiera incorporan porque están en desuso con la aparición de las memorias USB. La memoria debe estar vacía ya que se perderán todos sus datos. Con el programa Rufus para Windows seleccionado el archivo de la imagen ISO descargada y la unidad USB se crea el medio de instalación, en la siguiente página está explicado como crear una memoria USB arrancable en Windows.

Hay que conectar una memoria USB, seleccionarla, seleccionar el archivo de la imagen ISO de Ubuntu y pulsar el botón Empezar, al cabo de unos minutos la memoria estará lista para empezar a instalar Ubuntu.

Creación de medio de instalación en memoria USB dese Windows

Iniciar el sistema con el medio de instalación

Con el equipo apagado y la memoria USB contactada hay que iniciar el equipo para que se inicie desde la memoria USB. La forma de hacer que el equipo se inicie desde la memoria USB depende de cual sea el fabricante. Pulsando una tecla dependiendo de caso como F2, F8, F10, F12, ESC u otra se puede entrar en la BIOS o seleccionar el medio de instalación. La BIOS es una zona de configuración donde se modifican algunos parámetros del equipo muy importantes con lo que hay que tener cuidado de que se modifica para evitar comportamientos anómalos, a pesar de todo suele ser bastante intuitiva y si es un equipo reciente incluso con interfaz gráfica.

Según el fabricante e incluso modelos de la misma fabricante la tecla de acceso para iniciar desde el medio de instalación varía:

  • Acer: F2 o Delete
  • Asus: F2 o F10
  • Dell: F2, F1, Delete, F12 o F3
  • HP: F10 o Esc
  • Lenovo: F1 o F2
  • Sony: F2, F3, F1 o tecla assist
  • Toshiba: F2, F1, Esc

En las siguientes páginas puedes encontrar varias posibles teclas para entrar en la BIOS y cambiar la unidad de inicio del sistema según la marca, I, II y III.

Puede ser el caso de que cuando se inicia el equipo muestre un mensaje con la tecla que hay que pulsar si hay que probar hasta dar con ella. Después de pulsar la tecla de encendido poco después o según se muestra un logotipo es cuando hay que pulsar la tecla.

Si tu sistema tiene una BIOS de tipo UEFI, cualquier equipo del último lustro su BIOS será de este tipo, se debe desactivar la opción llamada Secure Boot que utiliza Windows como medida de seguridad pero que no está soportada aún en GNU/Linux.

Instalación de Ubuntu

Una vez iniciado el programa que guía en la instalación de Ubuntu hay que responder a algunas preguntas e introducir algunos pocos datos y en cuestión de menos de una hora el equipo ya está listo para empezar a usarse. En el artículo he utilizado la versión 16.04 LTS.

El asistente de instalación pregunta:

  • El idioma.
  • Si se quieren descargar las actualizaciones (recomendable) y software para reproducir mp3, flash así como controladores para la tarjeta gráfica y wifi.
  • Borrar el contenido del disco duro y si se quieren cifrar los datos del dispositivo de almacenamiento.
  • La clave para cifrar los datos del dispositivo de almacenamiento.
  • Una confirmación para proceder a borrar el disco duro e iniciar la instalación.
  • La zona horaria del usuario y la disposición del teclado.
  • El nombre del equipo, del usuario y la contraseña para iniciar sesión.

Los asistentes de instalación utilizan el entorno de escritorio del sabor que se está instalando pero los pasos son similares y piden la misma información.

Instalación de Ubuntu

Usando Ubuntu

Si se ha elegido cifrar el contenido del dispositivo de almacenamiento al realizar la instalación en el inicio del sistema Ubuntu pregunta por la contraseña para descifrar su contenido.

Ubuntu 16.04 con entorno de escritorio Unity
Ubuntu 16.04 con entorno de escritorio GNOME
Ubuntu 16.04 con entorno de escritorio KDE

Centro de software y actualizaciones

Ubuntu por defecto ya incorpora una buena cantidad de software preinstalado. En cualquier caso con la aplicación Software de Ubuntu se puede instalar más.

Al cabo de un tiempo de haber instalado Ubuntu se publicarán actualizaciones del software que tengas instalado con mejoras y correcciones de seguridad que son recomendables instalarlas usando la aplicación Actualizciones de software.

Instalar actualizaciones de seguridad y software

Ayuda

En internet hay cantidad de artículos en blogs o foros con ayuda que puedes encontrar con un buscador web como Google o DuckDuckGo. En ellos seguramente encontrarás una respuesta que te resuelva o ayude en cualquier problema que se te presente o duda que te surja. Y si después de haber buscado no encuentras la solución deja un comentario en este blog e intentaré ayudarte.

» Leer más, comentarios, etc...

Adrianistán

Mandando paquetes ICMP ECHO personalizados con Python

mayo 10, 2017 07:48

Estos días he estado experimentando un poco con una característica de las redes. En concreto he intentando ver si era posible lanzar un paquete a la red cuyo origen es una dirección broadcast y el receptor, al mandar la respuesta, lo hiciera sin darse cuenta a todos los equipos de la red. Esto en efecto podría usarse para inutilizar una red por Denial of Service.

ICMP ECHO

La prueba la he hecho con un ICMP ECHO pero podría hacerse con otros protocolos también, como DHCP.

Un ICMP ECHO es lo que hace el famoso comando pingping6 (en IPv6). Se trata de un protocolo de la capa de red (capa 3 en TCP/IP). ICMP dispone de varias operaciones para funcionar correctamente (Internet Control Message Protocol, controlar la red) pero la mayoría de ellas no se utilizan. Una que sí se usa es el ECHO, que permite mandar una información a un host y el host nos tiene que devolver lo mismo.

¿Cómo sabe a donde tiene que enviar la respuesta? A la IP de origen del primer paquete claro, pero ¿y si mentimos? ¿Y si le ponemos que la IP de origen es la IP de broadcast? Supuestamente, enviaría la respuesta a todos los demás hosts de la subred.

Script en Python

Para poder hacer los datagramas IP personalizados y poder mentir, usé raw sockets. Estos solo me han funcionado en Linux. El código es muy simple, la parte que más me costó fue el checksum pues las operaciones con bytes en Python son un poco curiosas, no existiendo el tipo byte pero si bytes.

import socket
import struct
import random
import binascii
import sys
import functools

ICMP_CODE = socket.getprotobyname("icmp")
ICMP_ECHO = 8
IP_SRC = "192.168.0.255"
IP_DST = "192.168.0.255"

def main():
    s = socket.socket(socket.AF_INET,socket.SOCK_RAW,socket.IPPROTO_ICMP)
    s.setsockopt(socket.SOL_IP,socket.IP_HDRINCL,1)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    packet_id = int((100000* random.random()) % 65535)
    packet = create_packet(packet_id)
    #print ("Size of packet: "+str(sys.getsizeof(packet)))
    s.sendto(packet,(IP_DST,0))

def create_header(data):
    version = 4 # IP version
    ihl = 5 # Numero de Bytes
    DF = 0
    Tlen = sys.getsizeof(data) + 20 # Longitud del datagrama
    ID = 1774 # ID de paquete
    Flag = 0 # Opciones
    Fragment = 0 # Numero de fragmento
    TTL = 128 # Tiempo de vida
    Proto = socket.IPPROTO_ICMP # Protocolo de los datos
    ip_checksum = checksum(data) # Checksum de los datos
    SIP = socket.inet_aton(IP_SRC) # Source IP address
    DIP = socket.inet_aton(IP_DST) # Destination IP address
    ver_ihl = (version << 4) + ihl
    f_f = (Flag << 13) + Fragment
    ip_hdr =  struct.pack("!BBHHHBBH4s4s", ver_ihl,DF,Tlen,ID,f_f,TTL,Proto,ip_checksum,SIP,DIP)
    return ip_hdr

def checksum(msg):
    flag = False
    suma = 0
    for byte in msg:
        if not flag:
            suma += (byte << 8)
        else:
            suma += byte
        flag = not flag
    resto = suma & 0xFFFF0000
    resto = resto >> 8
    suma += resto
    check = (~suma) & 0x0000FFFF
    return check

def create_data(id):
    header = struct.pack("bbHHh", ICMP_ECHO, 0, 0, id, 1)
    data = b"42"
    header = struct.pack("bbHHh", ICMP_ECHO, 0, socket.htons(checksum(header+data)), id, 1)
    return header + data

def create_packet(packet_id):
    data = create_data(packet_id)
    header = create_header(data)
    return header+data
while True:
    main()

Espero que a alguien le resulte interesante el código. Es un ejemplo de como generar datagramas sin la ayuda del sistema operativo. Además es importante saber que este tipo de programas solo pueden ejecutarse como root. Yo, por las pruebas que pude hacer, creo que los sistemas operativos actuales no son tontos y este tipo de ataques ya son conocidos. No pude capturar con Wireshark ninguno que fuese respuesta a broadcast, mientras que si la IP, aun siendo falsa, parecía real, sí que podía capturarla.
 

La entrada Mandando paquetes ICMP ECHO personalizados con Python aparece primero en Blog - Adrianistan.eu.

» Leer más, comentarios, etc...

Variable not found

11 años de Variable not found

mayo 10, 2017 06:55

11 años de Variable Not FoundDesde luego, conforme me voy haciendo más viejo, más rápido pasan los años, aunque probablemente esta sensación se deba también a que la fiesta de celebración del décimo aniversario se alargó varios meses y parece que fue ayer. Pero bueno, el caso es que aquí estamos, celebrando una vez más el cumpleaños de este blog :)

Once años dan para mucho, la verdad. Superamos ya las novecientas cincuenta publicaciones, más de 2.300 comentarios y 2,7 millones de páginas vistas según Blogger, cifras que van mucho más allá de lo que habría firmado sin dudarlo aquél mayo de 2006 cuando empezó este viaje.

Un viaje que tiene destino ni fecha de finalización: el único objetivo es disfrutar del camino, que os puedo asegurar que lo estoy haciendo, y echar una manita a los compañeros de profesión y afición que anden buscando información o soluciones a problemas con las que yo me haya topado antes. ¿Hay algo más gratificante que esto?

Pues sí, que no falte lo más importante: vosotros. Queridos amigos, muchas gracias por seguir el blog, compartir las publicaciones, comentarlas, contactar y, en definitiva, por estar ahí siempre regalando algo de vuestro tiempo para acercaros a este rinconcillo de la red.

El blog: las cifras del año

Durante este año continuamos la tendencia de leve crecimiento que ya llevamos observando algunos años. Es decir, los visitantes siguen creciendo a ritmo tranquilo, sin grandes sobresaltos en los datos:



Según Google, que todo lo sabe, durante este último año nos visitaron más de 152.000 usuarios distintos, visitando un total de 273.000 páginas, durante una media de algo más de un minuto. La página de Facebook del blog alcanza ya los 912 amigos (+14%) y a través de Twitter nos siguen cerca de 2.000 amigos (+40%), sumando los followers de mi cuenta personal (@jmaguilar) y la nueva cuenta del blog (@variablnotfound).

El 82% de los amigos de Variable not found sois hombres, lo cual era de esperar. Sin embargo, el número de mujeres ha crecido de nuevo este año, un 1% respecto al periodo anterior. El 67% de vosotros tenéis entre 25 y 34 años, sois principalmente amantes de la tecnología, el cine y la TV, y profesionales de este mundillo.

Chrome sigue siendo vuestro navegador favorito (76% y subiendo), seguido muy de lejos por Firefox (13%), Internet Explorer (4%), Safari (3%) y Edge (2%). Curiosamente, el número de visitantes con Safari ha subido un 87% respecto al año anterior, no sé si por la nueva oleada multiplataforma de .NET Core, o es simple casualidad.

El origen de los visitantes sigue siendo principalmente México y España, empatados a un 21% sobre el total. En tercera posición encontramos a Colombia, con el 10% de los visitantes, Perú con el 8%, Argentina un 7%, Chile (6%) y les siguen ya algo más rezagados Ecuador, Venezuela, y Estados Unidos.

Como suele ser habitual, la inmensa mayoría del tráfico procede de los buscadores (82%), básicamente Google. El tráfico directo trae sólo al 9% de los visitantes, los enlaces entrantes al 3%, y ha crecido especialmente el tráfico procedente de las redes sociales, que pasó del 0,3% del año anterior al 3% debido a un pequeño meneo sufrido el pasado mes de abril.

Creo que estos datos son suficientes para que conozcáis cómo va la cosa. En resumen, este sitio sigue siendo un blog pequeñito y humilde, pero estoy realmente orgulloso del punto a donde hemos conseguido llegar, de lo que hemos aprendido juntos y de los amigos que he ido encontrando por el camino.

Muchas gracias de nuevo vuestro apoyo durante todo este tiempo, y espero que sigáis por aquí un montón de años más, ayudándome a buscar la Variable.

Publicado en Variable not found.

» Leer más, comentarios, etc...

proyectos Ágiles

Master en Agile – MMA 2017

mayo 10, 2017 06:54

En octubre de 2017 se iniciará el Barcelona una nueva edición del Master en Métodos Ágiles (MMA) en La Salle (Universitat Ramon Llull). Tras 5 exitosas ediciones del formato anterior en forma de Postgrado y una de Máster, y dada la cantidad de conocimiento y áreas en las que se han ido extendiendo los principios ágiles, se ampliaron contenidos y profesorado para transformarlo en Máster, el primero a nivel mundial sobre Agile.

MMA-banner

Es una oportunidad única para aprender de profesionales de primer nivel, con varios años de experiencia específica en Agile, aplicando principios y métodos ágiles en contextos diversos, especializándose en aspectos concretos,  investigando sobre nuevas técnicas y ponentes en conferencias nacionales e incluso internacionales.

Asignaturas Temas Profesores
Fundamentos & Inception Principios y métodos más conocidos (Scrum, Lean, Kanban y XP). Facilitadores e impedimentos. Inception y conceptualización ágil de proyecto. Xavier Albaladejo
Agustín Yagüe
Scrum Estimación y planificación ágil, framework de Scrum, retrospectivas, métricas ágiles, herramientas ágiles físicas, radiadores de información. Xavier Quesada
Silvia Sistaré
Personas y equipos Gestión de personas, gestión de conflictos, motivación e incentivos, facilitación compartida, contratación ágil, coaching de equipos, liderazgo. Steven Wallace
Manuel Lopez

Joserra Díaz

Ingeniería Ágil User eXperiencie y prototipado en Agile, ALM ágil, eXtreme Programing, testing ágil, arquitectura ágil, arquitectura empresarial ágil, DevOps. Vicenç García-Altés

Pablo Gómez
Ángel Viudez
Marc Pifarré

TDD, BDD, Legacy code Desarrollo guiado por pruebas (de aceptación y unitarias), cómo trabajar con código heredado y reducir la deuda técnica. Carlos Ble
Rubén Bernárdez
Agustín Yagüe
Enterprise Learning & personal efficiency Comunidades de Práctica, Open Spaces, Talent development, gamification, Productividad y aprendizaje personal en Agile. Steven Wallace
Manuel Lopez
Vanesa Tejada
Kanban, Lean & continuous improvement Kanban, Lean Thinking, Lean Software Development, Mejora Continua en Agile Ángel Medinilla
Peter Kerschbaumer
Joserra Díaz
Cultura y Agile Management Tipos de cultura empresarial, gestión del cambio organizativo, Agile Management. Jasmina Nikolic
Joao Gama
Gabriel Prat
Lean Startup y Enterprise Product Management Lean Startup, innovación, Design Thinking, Impact Mapping, lanzamiento de startups ágiles, Agile Product Management, Product Portfolio Management, Roadmapping, Budgeting for Agile Gabriel Prat
Ángel Díaz-Maroto
Mattijas Larsson
Scaling Agile & Rollout Escalado (LESS, Spotify, Nexus, SAFe), desescalado y auto-organización empresarial (reinventing organizations, holocracy, …), contratos ágiles. Adrian Perreau
Fernando Palomo
Xavier Albaladejo
Trabajo Final de Máster Durante el Máster se elaborará un caso práctico de introducción y aplicación de Agile en una empresa, considerando la parte de transformación organizativa y de cultura

Algunos comentarios de los alumnos en ediciones anteriores en forma de Postgrado: “Cuando se acaba la clase, estamos ya esperando a que llegue la semana que viene para ver un nuevo tema con el siguiente profesor”. “Muy práctico”. “La calidad y diversidad de puntos de vista entre los profesores le aporta mucho valor”.  Más detalles en: Mejora de la situación laboral los alumnos del PMA trans un año.

Además de los conocimientos concretos que se reciben, uno de los principales cambios que han experimentado los alumnos es mayor perspectiva en los problemas, cómo abordar la complejidad en las empresas, en su trabajo y en las relaciones entre personas y en equipos. Han ganado discurso y aplomo para defender de manera más objetiva propuestas de cambio y mejora.

El Máster tendrá una duración de un año académico y se realizará viernes tarde y sábado por la mañana.

Para más detalles, consultar la página oficial del Máster.

–> Ver también cuál ha sido la Mejora de la situación laboral de los alumnos tras un año y los Principales aspectos valorados por los alumnos.


» Leer más, comentarios, etc...

Variable not found

Inline out variables en C# 7

mayo 09, 2017 08:51

C#Seguimos revisando las novedades que nos llegan de la mano de C# 7, la nueva versión del lenguaje aparecida junto a Visual Studio 2017.

En un post anterior ya profundizamos un poco en las funciones locales, y hoy veremos en qué consisten las nuevas inline out variables, una característica muy útil que nos ahorrará escribir código en escenarios en los que siempre hemos tenido la sensación de que C# podía hacer algo más por nosotros.

Esa extraña sensación…

Observad el siguiente código; seguro que habéis escrito algo parecido más de una vez (y dos, y tres… centenares ;D)
public void ShowInteger(string str)
{
int number;
if (int.TryParse(str, out number))
{
Console.WriteLine("Number: " + number);
}
}
En mi caso, cuando escribo un código de este tipo, es raro que antes de comenzar a escribir la línea del TryParse() haya previsto que necesitaré una variable int. Normalmente escribo las llamadas a métodos con parámetros out, y mientras voy haciéndolo me doy cuenta de que las necesito, por lo que tengo que tengo que volver atrás, insertar la línea para declarar de forma estrictamente tipada la variable de salida, y después continuar por donde estaba. No es que rompa la productividad de la jornada, pero realmente resulta algo molesto.

imageTambién he de decir que esta molestia se relajaba un poco con las versiones modernas de Visual Studio, pues las quick actions (Ctrl+.) ya nos ofrecen soluciones automáticas al problema. Lo mismo ocurre con Resharper, que puede detectar este caso y solucionarlo a golpe de Alt-Enter.

Otro inconveniente asociado a esta forma de definir los parámetros de salida es que muchas veces debíamos definir las variables en un ámbito superior a aquél en el que íbamos a utilizarlas. Por ejemplo, en el bloque de código que hemos visto antes, era habitual es que el entero number lo usáramos exclusivamente en el interior del bloque if, por lo que su declaración fuera de éste tampoco tenía mucho sentido.

Por todos estos motivos, la sensación de que C# se quedaba algo corto en este escenario siempre ha estado ahí, y esto es lo que viene a solucionarse en la versión 7.

Inline out variables

A partir de ahora podemos utilizar esta nueva sintaxis, más concisa y fácil de leer, usando inline out variables:
public void ShowInteger(string str)
{
if (int.TryParse(str, out int number))
{
Console.WriteLine("Number: " + number);
}
}
El resultado de este código es exactamente el mismo que vimos al principio. Internamente se crea una variable de tipo entero llamada number en el ámbito del método DoSomething(), que puede ser utilizada en cualquier punto del método una vez ha sido declarada:
Console.WriteLine("Number: " + number); // No compila: se usa "number" antes
                                        // de ser declarado

if (int.TryParse(str, out int number)) {
Console.WriteLine("Number: " + number); // Ok
}
Console.WriteLine("Number: " + number); // Ok, aunque "number" puede no haber
                                        // sido inicializado
Otro aspecto interesante, y que resulta bastante cómodo de utilizar, es que gracias a la inferencia de tipos podemos utilizar var para su declaración, pues ya el compilador es capaz de determinar de qué tipo se trata:
public void ShowInteger(string str)
{
if (int.TryParse(str, out var number))
{
Console.WriteLine("Number: " + number);
}
}
Por último, hay veces en las que invocamos un método con parámetros de salida cuyos valores no vamos a utilizar posteriormente. Para no obligarnos a declarar más variables de la cuenta, podemos utilizar el comodín "_" (guión bajo) para indicar al compilador que puede ignorar dichos valores:
public static void GetSomething(out int x, out double y, out string z)
{
x = 100;
y = 100.0;
z = "hello";
}

// Uso del método:
GetSomething(out var x, out _, out _);
Console.WriteLine(x); // Shows "100"
Visual Studio 2015 usando inline out vars¿Interesante, verdad? Pues recordad que, además de en Visual Studio 2017, también podéis usarlo en Visual Studio 2015 si instaláis o actualizáis a la última versión el paquete nuget "Microsoft.Net.Compilers"; aunque en el IDE se muestren como errores, la compilación irá bien y todo funcionará correctamente.

Publicado en Variable not found.

» Leer más, comentarios, etc...

Poesía Binaria

Haciendo SSH a través de SSH. Rápido y fácil con ProxyCommand.

mayo 08, 2017 03:10

SSH a través de SSH
Como vemos en las películas de hackers. ¡Alguien ha conectado con el servidor y no podemos averiguar su IP porque ha estado rebotando a través de varios servidores! Bueno, yo me quejaría un poco de la velocidad de la conexión entre mi ordenador y el ordenador destino cuando paso por dos servidores intermedios. Pero puede ser un buen ejercicio. A la vez que útil cuando queremos ocultar el acceso a nuestro servidor o tenemos que acceder a un ordenador que está en una red privada.

En el primer ejemplo me refiero a un servidor cuyo acceso SSH está cerrado a todas las IPs exceptuando las de una red o una máquina concreta. Por ejemplo, podemos abrir el puerto SSH de nuestro ordenador de casa o nuestro mediacenter sólo a la IP de un servidor de nuestra propiedad. Así, cuando nos hagan un scan de puertos, el puerto estará cerrado. Pero cuando quiera conectarme desde fuera, primero tendré que conectarme a mi servidor y desde ahí conectarme al mediacenter de casa.

En el segundo ejemplo, imaginad que tenemos un servidor web conectado directamente a Internet, y un servidor de base de datos conectado al servidor web. Si deseamos acceder al servidor de base de datos desde Internet tendremos que entrar primero al servidor web y desde ahí acceder al servidor de base de datos. Bueno, este esquema de red lo podemos complicar mucho más. Además, esquemas parecidos nos los podemos encontrar, por ejemplo, en Amazon, cuando hemos creado una VPC con subred pública y privada y queremos acceder a las máquinas de la subred privada.

Pinceladas de seguridad

Antes de nada, os recomiendo este post sobre Consejos para endurecer un servidor SSH y hacerlo más seguro. Con muchas cosas a tener en cuenta a la hora de montar nuestro servidor SSH y aislarlo de posibles ataques desde fuera.
Otro detalle más, y muy interesante es que lo que pongo en este post debemos hacerlo siempre en servidores de confianza. Es decir, puede que tengamos acceso a un servidor SSH que hemos encontrado por Internet, que sea muy rápido y todo muy bonito. Pero al final, la clave privada de acceso al segundo servidor va a pasar por el primero para poder conectar. Como algún administrador de sistemas esté atento se puede quedar con tu clave privada y las claves privadas no se pueden dar a nadie.

Por otra parte, al conectar con un servidor intermedio y estar enviando una clave privada, si alguien intercepta el tráfico con el primer servidor y consigue descifrarlo podrá entrar en los dos servidores en nuestro nombre. Aunque son cosas difíciles de descifrar… todo es posible. Siempre es importante tener actualizado tanto el cliente como el servidor SSH en todos los puntos para que la negociación de protocolos elija siempre los algoritmos más seguros disponibles.

El método clásico. SSH, entro, SSH, entro

Lo primero que se nos puede pasar por la cabeza es hacer SSH en al primer servidor y una vez dentro hacer SSH al segundo. Esto es sencillo cuando tenemos contraseñas. Es decir, para entrar en el primero nos pide introducir contraseña y luego para entrar en el segundo también. Luego para cerrar la sesión, hacemos exit en el segundo y seguidamente exit en el primero.
Pero siempre se recomienda utilizar pares de claves pública y privada (ver los consejos para endurecer un servidor SSH). Aunque ahora empieza a ser un poco incómodo porque conectar al primer servidor es inmediato. Ya que el servidor conoce nuestra clave pública podemos entrar directamente. Pero para entrar en el segundo servidor, es decir, nuestro destino, este segundo servidor tiene que tener la clave pública del primer servidor y el primero la clave privada correspondiente. Por lo que configurar un sistema así es arriesgado:

  • Por un lado, la clave privada de acceso al segundo servidor debe estar siempre en el primero. Cualquiera podría verla, sobre todo si el usuario dentro del servidor es compartido. Aunque no es una técnica recomendable, se utiliza.
  • Configurarlo todo es un rollo, y es muy fácil confundirse con las claves. Además, para copiar en el servidor no vamos a utilizar nuestra clave privada, utilizamos otra por si las moscas.
  • Acceder al servidor es lento, necesitamos ejecutar un comando intermedio. Y luego si no queremos sólo acceder sino que queremos copiar archivos, es mucho más lío copiar los archivos al primero y una vez copiados, copiarlos al segundo.

Otro método que podríamos utilizar. VPN

Otro método interesante sería crear una red VPN entre nuestro ordenador y el ordenador de destino. Pasaríamos por el servidor VPN y tendríamos la conexión cifrada. Sobre esa conexión estableceríamos la conexión por SSH y listo. Aunque tendríamos que tener de antes la VPN. De todas formas, el método que explicaré a continuación con ProxyCommand podríamos utilizarlo para entra en la máquina antes de tener la VPN montada.

Conectar con ProxyCommand

Este método ha sido inventado precisamente para conectar con un servidor intermedio. En este caso, hacemos que para conectar tengamos que ejecutar algo en el servidor intermedio. ¿Qué ejecutamos? ssh para conectar y nc (netcat) para que el primer servidor haga de puente. Veamos la línea de conexión más a fondo:

ssh -o ‘ProxyCommand=ssh usuario@intermedio.com nc %h %p’ usuario@final.com

Con esto, hacemos que se utilize la opción ProxyCommand que justo antes de conectar hará ssh al intermedio.com (nuestro servidor intermedio) con el usuario usuario y seguidamente ejecutará nc al host y puerto con el que vamos a conectar. En nuestro caso el host sería final.com y el puerto 22 para SSH (aunque como veremos en futuros ejemplos, podremos variar estos puertos).

Perfectamente podríamos cambiar los puertos, por ejemplo SSH al puerto 221 para el servidor intermedio y el puerto 222 para el servidor final:

ssh -p222 -o ‘ProxyCommand=ssh -p221 usuario@intermedio.com nc %h %p’ usuario@final.com

Conectando de esta forma, la clave privada no tiene por qué estar almacenada en el servidor intermedio todo el tiempo, ni tampoco tendríamos que añadir una clave pública extra al servidor final. Directamente las cogerá de nuestro directorio ~/.ssh/ local. Y ssh se encargará de hacer la negociación de claves y protocolos.

Esto también podríamos añadirlo en nuestro archivo ~/.ssh/config con la siguiente información:

Host final.com
ProxyCommand ssh -p221 usuario@intermedio.com nc %h %p
Port 222

Ahora, haciendo sólo:

ssh usuario@final.com

Conectaría automáticamente con el proxy. Es decir, sería transparente para nosotros y no tendríamos que especificar el ProxyCommand todo el rato para conectar. Aún así hemos de ser conscientes que se ejecuta un netcat en el servidor, es decir, en ese punto, la información está sin cifrar. Si alguien mete mano en el nc estamos perdidos. Por lo tanto, hacedlo siempre en servidores de confianza. Además, si se compromete el servidor intermedio, tal vez no se haya comprometido sólo la clave privada para el servidor final. Así que cuidado.

Transfiriendo archivos

Podemos hacerlo con scp. Si en nuestro ~/.ssh/config hemos hecho las modificaciones anteriormente mencionadas no habrá problema, podremos hacer scp sin mover un dedo. Pero, ¿cómo sería el comando para hacer scp?

scp -P222 -o ‘ProxyCommand=ssh -p221 usuario@intermedio.com nc %h %p’ fichero_origen usuario@final.com:directorio_o_fichero_destino

Aunque lo interesante es hacerlo con rsync que nos da muchas facilidades y ventajas frente a la transmisión con scp:

rsync -avhP -e “ssh -p222 -o ‘ProxyCommand=ssh -p 221 usuario@intermedio.com nc %h %p'” edid_monitor fichero__o_directorio_origen usuario@final:directorio_o_fichero_destino

Aunque los argumentos -avhP no son estrictamente necesarios. Con rsync tengo siempre esta coletilla que me vale para la mayoría de los casos. Pero añadiremos -e con el comando para ejecutar ssh y tendremos que añadir toda la línea de conexión. Aunque, como antes, si lo tenemos configurado en ~/.ssh/config no hace falta.

Notas finales

Para realizar este tipo de conexión, debemos tener acceso al servidor intermedio y el servidor intermedio deberá tener acceso al segundo. Pero no es necesario que tengamos acceso al servidor final, es más, puede que no tengamos ping, puede que el servidor final, como dije al principio esté dentro de una red privada y el intermedio sea sólo el punto de entrada. Aunque lo pongamos en nuestro archivo de configuración (~/.ssh/config) podemos poner una IP privada a la que no tenemos acceso (siempre es mejor que los hosts tengan su nombre, pero no nos vamos a morir si no es así).
Pero insisto, el servidor intermedio sí que debe tener acceso.

Foto principal: Metropolitan transportation

The post Haciendo SSH a través de SSH. Rápido y fácil con ProxyCommand. appeared first on Poesía Binaria.

» Leer más, comentarios, etc...

Jesús Perales

Nginx vs Apache

mayo 04, 2017 05:45

Nginx vs Apache

Hasta hace algunos años siempre que se hablaba de montar un servidor web rondaba el nombre de Apache y por lo general era la opción inicial, ahora las cosas han cambiado y decidí recopilar información de fuentes confiables, traducirla al español, de por que Apache ya no es la mejor opción, al menos no de la antigua forma.

Apache es un servidor desarrollado en 1995, es una plataforma muy estable diseñada para ser extendida mediante módulos.

Los modulos de Apache lo proveen de muchas funcionalidades, entre ellas la posibilidad de servir contenido dinámico y ello dio paso a el stack XAMPP(Apache, MariaDB[Antes se usaba MySQL], PHP, Perl).

Nginx vs Apache

Apache esta diseñado para crear un thread/hilo por cada cliente que necesite ser atendido, este aislamiento ayudo a agilizar el desarrollo y la innovación.

La innovación trajo consigo un gran crecimiento en Internet y los usuarios comenzaron a crecer exponencialmente.

Nginx vs Apache

A su vez los componentes de las paginas comenzaron a ser mas y mas pesados y los usuarios menos pacientes al esperar que una pagina web cargue completamente.

Nginx vs Apache

Los cambios en el volumen de trafico de usuarios y páginas pesadas comenzaron a ser un desafío al modelo de un thread/hilo por usuario que tanto ayudo a Apache en un principio.

Sumado a eso comenzó a extenderse una practica llamada HTTP keepalive que permite disminuir el tiempo de carga de una página haciendo peticiones paralelas de los recursos, cada petición abierta es atendida por un proceso httpd, por esta razón Apache necesita crear numerosos procesos largos.

Nginx vs Apache

Para mejorar la portabilidad y escalabilidad en algunas plataformas, los principales desarrolladores de Apache crearon dos modelos de procesamiento adicionales (denominados módulos multiprocesamiento o MPM).

El MPM reemplazó los procesos separados de httpd con un pequeño número de procesos secundarios que ejecutaban múltiples subprocesos de trabajo y asignaban un subproceso por conexión. Esto fue útil en muchas versiones comerciales de Unix (como el AIX de IBM) donde los hilos son mucho más ligeros que los procesos, pero es menos efectivo en Linux donde los hilos y procesos son solo encarnaciones diferentes de la misma entidad del sistema operativo.

Más tarde, Apache añadió el event MPM, que amplía el MPM añadiendo un hilo escucha independiente que gestiona las conexiones de mantenimiento de inactividad una vez que la solicitud HTTP se ha completado.

Estas medidas sirven para mejorar el rendimiento, pero el modelo monolítico de un solo servidor que fue clave para el éxito temprano de Apache ha seguido luchando a medida que aumentan los niveles de tráfico y las páginas web se vuelven más y más pesadas.

El modelo pesado y monolítico de Apache tiene sus límites

El desempeño en los benchmarks de laboratorio a menudo no se reproduce en implementaciones de producción en vivo en sitios web ocupados y el ajuste de Apache para hacer frente al tráfico del mundo real es un arte complejo. De forma poco equitativa, Apache ha ganado una reputación como un servidor web hinchado, excesivamente complejo y limitado al rendimiento que puede ser explotado por ataques lentos de denegación de servicio (DoS).

Hasta aquí podemos saber un poco de historia de Internet como funcionan muchos de los servidores creados a día de hoy, ya que muchos utilizan Apache como base, sus problemas así como sus soluciones.

Introducción a NGINX - Diseñado para alta concurrencia

NGINX fue escrito específicamente para abordar las limitaciones de rendimiento de los servidores web Apache.

Fue creado en 2002 por Igor Sysoev, un administrador de sistemas para un popular sitio ruso (Rambler.ru), como una solución escalable para ayudar al sitio a administrar mayores y mayores volúmenes de tráfico.

Se convirtió en opensource en octubre de 2004, en el 47 aniversario del lanzamiento de Sputnik.

NGINX puede ser desplegado como un servidor web independiente, y como un proxy de frontend para Apache y otros servidores web.

Esta solución de despliegue actúa como un dispositivo de descarga de red frente a los servidores Apache, traduciendo las conexiones lentas del lado de Internet en conexiones rápidas y confiables del lado del servidor, y descargando completamente las conexiones keepalive de los servidores Apache.

El efecto neto es restaurar el rendimiento de Apache a niveles cercanos a los que los administradores ven en un punto de referencia local.

NGINX también actúa como un amortiguador de choque, protegiendo a los servidores vulnerables de Apache de picos en el tráfico y de ataques de conexión lenta como Slowloris y slowhttprequest.

El secreto en la arquitectura

El rendimiento y la escalabilidad de NGINX surgen de su arquitectura basada en eventos. Difiere significativamente del enfoque de proceso o hilo por conexión de Apache, en NGINX, cada proceso de trabajo puede manejar miles de conexiones HTTP simultáneamente. Esto resulta en una implementación considerada altamente como ligera, escalable y de alto rendimiento.

Nginx vs Apache

Para muchos tipos de aplicaciones, NGINX y Apache se complementan bien, por lo que suele ser más apropiado hablar de "NGINX y Apache" en lugar de "NGINX vs. Apache". Un patrón de inicio muy común es desplegar el software NGINX de código abierto como proxy (o NGINX Plus como plataforma de entrega de aplicaciones) frente a una aplicación web basada en Apache. NGINX realiza el levantamiento pesado relacionado con HTTP: sirve archivos estáticos, almacenamiento en caché de contenido y descarga de conexiones HTTP lentas, para que el servidor Apache pueda ejecutar el código de la aplicación en un entorno seguro.

NGINX proporciona todas las características principales de un servidor web, sin sacrificar las cualidades ligeras y de alto rendimiento que lo han hecho exitoso, y también puede servir como un proxy que reenvía las solicitudes HTTP a servidores web ascendentes (como un backend de Apache) y FastCGI, memcached, SCGI y uWSGI.

Nginx vs Apache

NGINX no busca implementar la enorme gama de funcionalidades necesarias para ejecutar una aplicación, sino que depende de servidores especializados de terceros como PHP-FPM, Node.js e incluso Apache.

“Apache is like Microsoft Word. It has a million options but you only need six. NGINX does those six things, and it does five of them 50 times faster than Apache.” — Chris Lea

Nginx vs Apache

Como podemos ver NGINX es un proyecto enfocado en la alta disponibilidad de los servicios, pero se enfoca en servir contenido estático y hacerla de proxy/conector entre otros servidores para darles mayor seguridad y ayudar a manejar el enorme trafico de usuarios.

Nginx vs Apache

Actualmente NGINX es utilizado por empresas como WIX, Wordpress y la NASA.

Es posible utilizar el soporte comunitario total mente gratis y también se tienen tres niveles de soporte de paga profesional ofrecido por NGINX, Inc.:

  • Básico ($1,900 US / year): Para los despliegues no críticos de NGINX en los que los tiempos de respuesta más largos son aceptables y no se requieren revisiones en caliente para implementaciones de producción.

  • Profesional ($3,000 US / year): Para el despliegue de producción de NGINX y NGINX Plus, o donde se requiera el manejo de casos prioritarios.

  • Enterprise ($4,500 US / year): Para despliegues de misión crítica de NGINX o NGINX Plus que requieren el nivel más alto de soporte con tiempos de respuesta más rápidos y soluciones a través de consultas telefónicas o web.

¿Qué cubre el soporte comercial de NGINX?

  • El uso de NGINX opensource y NGINX Plus

  • Búsqueda y corrección de errores.

  • Actualizaciones de software.

  • Asistencia con la instalación.

  • Notificaciones de seguridad.

  • Discrepancias en la documentación.

Nginx vs Apache

Conclusión:

Como podemos ver Apache como tal no esta muerto y no quiere decir que tengamos que dejar de utilizarlo y utilizar siempre NGINX, de hecho se recomienda utilizarlo junto con.

Simplemente es necesario combinarlo con los nuevos proyectos que están enfocados a solucionar problemas muy específicos en los cuales Apache o cualquier otro servidor no son buenos, en este caso NGINX, tiene los problemas más comunes de Apache resueltos pues así fue como nació.

También podemos ver que se tiene un soporte comercial y denota mucha madurez en el proyecto ya que es una empresa constituida y no es un proyecto que de la noche a la mañana pueda desaparecer, ver el peso y renombre de sus clientes da mucha confianza en ellos.

Fuentes:

» Leer más, comentarios, etc...

Meta-Info

¿Que es?

Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.

rss subscripción

Sponsors

Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
planetacodigo

planetacodigo

Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

Idea: Juanjo Navarro

Diseño: Albin