miércoles, 29 de julio de 2015

git: mostrar la lista de archivos de un commit

Para mostrar la lista de archivos de un commit necesitamos primero utilizar el comando:

$ git log

Se abrirá pantalla con less y de ahí copiaremos el commit id y una vez que se copie, ejecutamos el siguiente comando pegandolo al final:

$ git diff-tree --name-only -r dfaja8asas5dasasas440asasas93213af4053da07b7f8


Espero te sea de utilidad !



Referencias:
http://stackoverflow.com/questions/424071/list-all-the-files-for-a-commit-in-git

lunes, 13 de julio de 2015

Include como php en Python + Django

En uno de los proyectos que estoy trabajando me tope con este detalle después de buscar en varios foros y demás encontre la siguiente forma, nada más cuidado por que baja el rendimiento, y hay que revisar las cuestiones de seguridad (http://lucumr.pocoo.org/2011/2/1/exec-in-python/); pero eso si funciona perfectamente y puede servir dependiendo de la aplicación; esto se lográ utilizando la instrucción exec.

El proyecto completo lo pueden descargar de: https://github.com/omaryahir/django_doing_includes

Aquí comento la parte importante dentro del archivo models.py estoy agregando un fragmento de código que manda llamar el archivo prueba.py :


db/models.py:

from django.db import models

class Person(models.Model):
    first_name = models.CharField(verbose_name=u'Nombre', max_length=50)
    last_name = models.CharField(verbose_name=u'Apellido', max_length=50)
    initials = models.CharField(verbose_name=u'Iniciales', max_length=10)

    def save(self, *args, **kwargs):
        prueba_py = open('db/prueba.py','r')
        super(Person, self).save(*args, **kwargs)
        exec(prueba_py)
        print self.initials

    def __unicode__(self):
        return "%s %s" % (self.first_name, self.last_name)


class Otro(models.Model):
    otrocampo = models.CharField("otro campo", max_length=50)
    person = models.ForeignKey(Person)

    class Meta:
        verbose_name = "Otro"
        verbose_name_plural = "Otros"

db/prueba.py:

self.initials = "Esta es la prueba"
x = Otro()
x.otrocampo = "Prueba otro campo"
x.person = self
x.save()
print "Saliendo"

Como pueden observar en el código la línea - prueba_py = open('db/prueba.py','r')- de la clase Person se abre el archivo prueba.py y posteriormente en la línea - exec(prueba_py) - ejecutamos su contenido; lo interesante aquí de python es que carga todo el contexto, algo similar a lo que se hacia con php haciendo un include.

Podemos observar en el archivo prueba.py que dentro del archivo usamos las variables como si estas se encontrarán ahí, bien sin embargo en python una de las cualidades que tenemos el rendimiento, por lo que este tipo de usos puede afectarlo, se debe analizar en donde se requerirá su uso.

Si encuentras otra forma no dudes en compartirla ...

Saludos espero te sea de utilidad !


Referencias:
https://docs.python.org/3/library/functions.html?highlight=exec#exec
http://lucumr.pocoo.org/2011/2/1/exec-in-python/
https://github.com/omaryahir/django_doing_includes

domingo, 12 de julio de 2015

Nginx bloquear el acceso a un directorio estático

En uno de los sitios que me toco configurar necesite bloquear el acceso a un subdirectorio de un directorio de contenido estático, mientras que el acceso al contenido de los demás subdirectorios debe permanecer disponible, encontre la siguiente forma de hacerlo:

En el archivo de configuración del sitio agregue las líneas en negritas:

server {
    listen   80;
    ...
    location ~/static/carpetabloquear/ {
        alias /webapps/ruta/al/contenido/static/carpetabloquear/;
    }

    location /static/ {

        alias /webapps/ruta/al/contenido/static/;
    }
    ...
}


De esta forma aunque el usuario tiene acceso para algunos archivos del media dentro del directorio de la carpeta a bloquear no tiene acceso. Fue la forma como encontre hacerlo si has encontrado otra, te agradezco compartirlo.


Espero te sea de utilidad !


Referencias:
http://www.nginxtips.com/nginx-location-directive/

Django: ubuntu + nginx + gunicorn + supervisor + mysql

Tengo que instalar en una maquina virtual con virtualbox un deployment de un proyecto que debo entregar dejaré aqui los pasos que me funcionaron, ya tenía un post de deployment con uwsgi, pero ha quedado un poco desactualizado.

Bien voy colocando cada uno de los comandos:

$ sudo apt-get install python-virtualenv

Hay algunas otras herramientas que necesitamos instalar para el uso de django en ubuntu:

$ sudo apt-get install mysql-server
$ sudo apt-get install libmysql++-dev
$ sudo apt-get install python-dev
$ sudo apt-get install python-mysqldb
$ sudo apt-get install build-essential python

Crear una carpeta donde tendremos nuestras aplicaciones web:

$ sudo mkdir -p /webapps/carpeta_proyecto
$ sudo chown administrador /webapps/carpeta_proyecto

Creamos nuestro directorio virtual:

$ cd /webapps/carpeta_proyecto
$ virtualenv venv
$ source venv/bin/activate

Cargamos en ese directorio una carpeta con el código de nuestro proyecto, en mi caso lo tengo en bitbucket por lo que usando este comando descargo el código.

(venv)$ git clone http://bitbucket.org/tu_usuario/miproyecto.git

De esta forma tendremos dos directorios uno con el nombre de nuestro proyecto <miproyecto> y por otro lado tendremos un directorio con el entorno virtual <venv>.

Ahora instalamos el entorno en mi proyecto tengo un archivo requirements.txt, pero igual mínimo necesitamos instalar django y la librería de mysql, lo instalamos usando pip.

(venv)$ pip install django
(venv)$ pip install python-mysql

Es probable que para el proyecto tengan que correr un python manage.py syncdb o migrate para que puedan cargar la base de datos del proyecto, hasta este punto debemos poder probar el proyecto y ver que se encuentre funcionando correctamente usando un runserver.

Una vez que lo anterior se encuentre funcionando vamos ahora a realizar directamente el deployment.

Primero iniciamos instalando gunicorn, para eso utilizamos:

(venv)$ pip install gunicorn

Podemos probar el funcionamiento de gunicorn utilizando:

(venv)$ cd miproyecto
(venv)$ gunicorn miproyecto.wsgi:application --bind 0.0.0.0:8080

NOTA: La carpeta miproyecto, es el directorio que django crea cuando ejecutamos un startproject.

Al ejecutar el comando anterior gunicorn inicia un servidor en el puerto 8080 para ejecutar nuestro proyecto, sin embargo puede ser que el contenido estático no funcione correctamente.

Ahora para hacerlo más dinámico realizamos lo siguiente, creamos un archivo en mi caso yo lo deje en carpeta_proyecto/deployment/gunicorn_run y le copiamos dentro el siguiente contenido:

#!/bin/bash

NAME="miproyecto_app"                                        # Nombre de la app
DJANGODIR=/webapps/carpeta_proyecto/miproyecto               # directorio del proyecto de Django
SOCKFILE=/webapps/carpeta_proyecto/deployment/gunicorn.sock  # Nos comunicaremos utilizando este unix socket
USER=miusuario                                               # Correr con el usuario
GROUP=grupousuario                                           # Correr como el grupo 
NUM_WORKERS=3                                                # Cuantos - worker processes - de Gunicorn 
DJANGO_SETTINGS_MODULE=miproyecto.settings                   # Archivo settings de Django
DJANGO_WSGI_MODULE=miproyecto.wsgi                           # Archivo WSGI del proyecto

echo "Starting $NAME as `whoami`"

# Activando el entorno
cd $DJANGODIR
source ../venv/bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH

# Crear el directorio para correrlo en caso de no existir
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR

# Iniciando Django Gunicorn
exec ../venv/bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
  --name $NAME \
  --workers $NUM_WORKERS \
  --user=$USER --group=$GROUP \
  --bind=unix:$SOCKFILE \
  --log-level=debug \
  --log-file=-


Posteriormente convertimos el archivo como ejecutable usando el comando:

(venv)$ sudo chmod u+x gunicorn_run

Para probar el gunicorn podemos ejecutar el archivo de esta forma hacemos lo siguiente:

(venv)$ ./gunicorn_run

Una vez que se haya logrado ejecutar sin problemas, ahora, instalamos supervisor.

(venv)$ sudo apt-get install supervisor

Después de instalar supervisor vamos a crear el archivo /etc/supervisor/conf.d/miproyecto.conf con el siguiente contenido:

[program:miproyecto]
command = /webapps/carpeta_proyecto/deployment/gunicorn_run               ; Comando para iniciar la app
user = miusuario                                                          ; Usuario que lo va ejecutar
stdout_logfile = /webapps/carpeta_proyecto/logs/gunicorn_supervisor.log   ; Ruta del archivo log
redirect_stderr = true                                                    ; Alamcenar stderr en el mismo log
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8                           ; Establecer UTF-8 por default

Creamos el directorio logs y el archivo para almacenar el gunicorn_supervisor.log dentro del directorio de carpeta_proyecto.

(venv)$ mkdir /webapps/carpeta_proyecto/logs
(venv)$ touch /webapps/carpeta_proyecto/logs/gunicorn_supervisor.log

Posteriormente utilizamos para cargar el supervisor:

(venv)$ sudo supervisorctl reread
miproyecto: available
(venv)$ sudo supervisorctl update
miproyecto: added process group

Ahora para revisar el estatus del proyecto podemos utilizar:

(venv)$ sudo supervisorctl status miproyecto
miproyecto                            RUNNING    pid 2277, uptime 0:01:40

Podemos iniciar, parar o reiniciar el proyecto utilizando:

(venv)$ sudo supervisorctl stop miproyecto
miproyecto: stopped
(venv)$ sudo supervisorctl start miproyecto
miproyecto: started
(venv)$ sudo supervisorctl restart miproyecto
miproyecto: stopped
miproyecto: started

Ahora vamos con Nginx, para instalarlo utilizamos:
(venv)$ sudo apt-get install nginx

Para iniciar el servicio podemos utilizar:
$ sudo service nginx start

Con esto el servidor de nginx se activará, puede probarse, por omisión el puerto es el 80. Ahora bien lo que haremos es crear el archivo /etc/nginx/sites-available/miproyecto con el siguiente contenido:

upstream miproyecto_app_server {
  # fail_timeout=0 means we always retry an upstream even if it failed
  # to return a good HTTP response (in case the Unicorn master nukes a
  # single worker for timing out).

  server unix:/webapps/carpeta_proyecto/deployment/gunicorn.sock fail_timeout=0;
}

server {

    listen   80;
    server_name example.com;

    client_max_body_size 4G;

    access_log /webapps/carpeta_proyecto/logs/nginx-access.log;
    error_log /webapps/carpeta_proyecto/logs/nginx-error.log;

    location /static/ {
        # path to static folder         alias   /webapps/carpeta_proyecto/miproyecto/static/
    }
    
    location /media/ {
        # path to media folder
        alias   /webapps/carpeta_proyecto/miproyecto/media/;
    }

    location / {
        # an HTTP header important enough to have its own Wikipedia entry:
        #   http://en.wikipedia.org/wiki/X-Forwarded-For
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # enable this if and only if you use HTTPS, this helps Rack
        # set the proper protocol for doing redirects:
        # proxy_set_header X-Forwarded-Proto https;

        # pass the Host: header from the client right along so redirects
        # can be set properly within the Rack application
        proxy_set_header Host $http_host;

        # we don't want nginx trying to do something clever with
        # redirects, we set the Host: header above already.
        proxy_redirect off;

        # set "proxy_buffering off" *only* for Rainbows! when doing
        # Comet/long-poll stuff.  It's also safe to set if you're
        # using only serving fast clients with Unicorn + nginx.
        # Otherwise you _want_ nginx to buffer responses to slow
        # clients, really.
        # proxy_buffering off;

        # Try to serve static files from nginx, no point in making an
        # *application* server like Unicorn/Rainbows! serve static files.
        if (!-f $request_filename) {
            proxy_pass http://miproyecto_app_server;
            break;
        }
    }

    # Error pages
    error_page 500 502 503 504 /500.html;
    location = /500.html {
        root /webapps/carpeta_proyecto/miproyecto/static/;
    }
}

De la misma manera que en los archivos anteriores personalizamos el contenido donde el color esta en negritas.

Ahora creamos el symbolic link en la carpeta sites-enabled (Esta carpeta nos permite indicar a nginx cuales sitios están habilitados).

$ sudo ln -s /etc/nginx/sites-available/miproyecto /etc/nginx/sites-enabled/miproyecto

Posteriormente reiniciamos nuestro servidor nginx:

$ sudo service nginx restart

Si hay algún error hay que revisar los directorios de los archivos, por otro lado en caso de que aparezca la pantalla de bienvenida de nginx al momento de volver a probar es debido al archivo default, en caso de que no vayamos a utilizar podemos eliminar su archivo símbolico desde el directorio de sites-enabled, una vez realizado lo anterior reiniciamos de nuevo el servidor de nginx.

$ sudo service nginx restart

Posterior a esto deberá funcionar correctamente el sitio.


Espero te sea de utilidad !



Referencias:
http://michal.karzynski.pl/blog/2013/06/09/django-nginx-gunicorn-virtualenv-supervisor/
http://michal.karzynski.pl/blog/2013/10/29/serving-multiple-django-applications-with-nginx-gunicorn-supervisor/

domingo, 11 de enero de 2015

virtualenvwrapper en mac osx

Para instalar virtualenvwrapper se debe hacer con pip, siguiendo estos comandos:

$ sudo easy_install pip
$ sudo pip install virtualenv
$ sudo pip install virtualenvwrapper

Es posible que pip o virtualenv ya los tengas instalados así que si es así puedes omitir esos pasos, ahora bien, aquí viene por que no me funcionaba a mi, debes editar el archivo ~/.bashrc o ~/.zshrc (si estas usando oh my zsh, altamente recomendable) y colocar la siguiente línea:


source /usr/local/bin/virtualenvwrapper.sh

Con lo anterior estará funcionando el virtualenvwrapper, al parecer todo el asunto esta que lo cargue antes, fue una forma que encontre de resolverlo, si encontraste alguna otra no dudes en compartirla.

Espero te sea de utilidad !


Referencias:

jueves, 8 de enero de 2015

unix: var run supervisor.sock or tmp.sock no such file o no encontrado

Después de haber cargado un servidor en suse con un deploy con Django sobre nginx, supervisor y gunicorn (Aquí la guía que seguí) tuvimos un proceso de reinicio de servidor y posteriormente al querer correr el nginx con el supervisor marcaba el error:

unix:///var/run/tmp.sock no such file

Buscando en internet encontré que también podría marcar el error de la siguientes formas:

unix:///var/run/supervisor.sock archivo no encontrado
unix:///var/run/supervisor.sock no such file

El detalle es que el supervisor tiene que ser reiniciado de forma manual de acuerdo a la referencia entonces se necesita realizar nuevamente el comando:

$ sudo supervisord

De esta forma se reiniciará y cargará nuevamente el supervisor, es importante recordar que se tiene que estar en el directorio del archivo supervisord.conf

Gracias a la referencia fue que encontré la solución.


Espero te sea de utilidad !


Referencias:
https://github.com/Supervisor/supervisor/issues/121


jueves, 11 de diciembre de 2014

Error occurred during initialization of VM Could not allocate metaspace: 1073741824 bytes SUSE Amazon AWS

Instalando Java en un servidor suse tuve el siguiente problema:

#java --version
Error occurred during initialization of VM
Could not allocate metaspace: 1073741824 bytes

Empezando para instalarlo descargue el rpm y seguí el procedimiento del siguiente sitio:
http://docs.oracle.com/javase/8/docs/technotes/guides/install/linux_jre.html#CFHIEGAA

Después de buscar en varios sitios, ejecutando el siguiente comando:

# java -XX:-UseCompressedClassPointers -XX:+PrintFlagsFinal LongSleep

Se ve un detallado del uso de memoria por flag, y me encontre que justo la línea:
 uintx CompressedClassSpaceSize                  = 1073741824                          {product}

Entonces siguiente los sitios de refencias, ejecutando la siguiente instrucción si opera correctamente java:

# java -XX:CompressedClassSpaceSize=10m -version
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)

De esa manera le estoy indicando que solo use 10 megas para ejecutarlo, o también usando:

# java -XX:-UseCompressedClassPointers -version
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)


Referencias:
http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2014-April/011319.html
http://arabhardware.net/forum/showthread.php?t=391068
http://docs.oracle.com/javase/8/docs/technotes/guides/install/linux_jre.html#CFHIEGAA