Thursday, November 13, 2014

Ftp server with zero configuration

Log in to the server, pip install pyftpdlib and type in python interpreter
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer
authorizer = DummyAuthorizer()
authorizer.add_user('test', 'test37', '/some/dir/')
handler = FTPHandler
handler.authorizer = authorizer
server = FTPServer(('0.0.0.0', 5021), handler)
server.serve_forever()
Try it out
~$ ftp
ftp> open X.X.X.X 5021
Connected to X.X.X.X.
220 pyftpdlib 1.4.0 ready.
Name (X.X.X.X:adolgarev): test
331 Username ok, send password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> passive
Passive mode on.
ftp> ls
227 Entering passive mode (X,X,X,X,X,X).
150 File status okay. About to open data connection.
-rw-r--r--   1 4001     4001      3622358 Aug 20 08:17 xxx
drwxr-xr-x   3 4001     4001         4096 Jul 09 10:57 xxx
-rw-r--r--   1 4000     4000      3585261 Jul 09 12:49 xxx
drwxr-xr-x   3 4000     4000         4096 Aug 20 08:35 xxx
226 Transfer complete.
Even more, it is surprisingly fast, see comparison to other implementations.

Wednesday, October 15, 2014

Tuesday, September 9, 2014

What one can learn from Game AI development

Below is an excerpt from STRIPS: A New Approach to the Application of Theorem Proving to Problem Solving, R. E. Fikes and N. J. Nilsson, Artificial Intelligence 2 (3--4), 1971. (pdf):
STRIPS belongs to the class of problem solvers that search a space of “world models” to find one in which a given goal is achieved. For any world model, we assume there exists a set of applicable operators each of which transforms the world model to some other world model. The task of the problem solver is to find some composition of operators that transforms a given initial world model into one that satisfies some particular goal condition.
The basic idea is that a world model is modified by operators, which have a set of preconditions and side effects. STRIPS planner is used to find out how to apply these operators to achieve the goal given some state. (But don't confuse this approach with a Prolog programming language that operates with formal logic on top of knowledge base without any side effects.) The original algorithm without any optimizations is simple: find which operator achieves the goal, then if operator's prerequisites are not satisfied your new goal is to satisfy those, in the end choose the easiest plan. STRIPS was featured in F.E.A.R. and a number of other games, that was (and to some degree still is) a cutting edge in game AI development.

The main thing one can learn from this is a clear segregation between WHAT and HOW. WHAT is your goal defined in terms of conditions applied to the state (defines a subset of all possible states). HOW is a set of operators that do the job. Everything else does planner that doesn't depend on the domain and can be easily reused from project to project.

An example
Imagine you are about to implement private cloud solution. You can implement a set of operators like bring interface up, make a bridge, obtain address via DHCP, mount volume, create container with lxc, etc. Each of these operators have prerequisites like to obtain address via DHCP an interface must be up and running. Define states in terms of MIBs and use SNMPv3 to get/set state. Then you can easily define goals like provision a vm and planner will do it for you using defined operators. The good news is that if something happens in the middle of vm provisioning (state changed from A to A') planner can deal with this by providing a new plan. If you need to integrate someones solution just add a few new operators and planner will benefit from them immediately. Compare and contrast this approach to OpenStack solution that is obsessed by (micro-)SOA ideas not in the best way.
Can this be applied to the web development? Consider you have a bunch of operators with arguments, prerequisites and side effects defined. In case one does not handle these operators as black boxes and with the bit of introspection understands prerequisites and side effects planner can build workflows by connecting operators together and it can also build an interface to input arguments for operators in the plan and react to unexpected (what if Paypal payment failed, planner can suggest you to pay in another way). The only thing left is to present current state in a nice way to the user.

Final thoughts
One day devs used macro assembler, then C, nowadays OOP and FP hit the fan, but we need to go further and program in terms of business rules and goals. Even AngularJS and Backbone are too low level.

Wednesday, September 3, 2014

Glue together git, feature branches, Jenkins and Redmine

Feature branches or topic branches are useful thing to keep master stable and to introduce atomicity and isolation to what you are doing. But when you commit your work and set task to Resolved state it doesn't mean that this fix is ready to be tested by QA team. There is a time lag between the moment you resolve an issue in issue tracker and it is rolled out on test environment: your lead needs to review your changes, QA lead needs to make a build that will grab your change and put it to the testing env.
There is a simple solution to this issue though. First of all a custom field has been added to the tracker (issue/bug/feature/ticket) in Redmine namely Issue fixed build number (ok, it must have been called Issue fixed commit), when someone resolves a ticket it fills in the last commit in corresponding feature branch. If one sees this commit in some branch he can say with confidence that this branch contains changes for this feature (after you merge feature branch to the master you'll see there the same commit hash, it doesn't hold for rebase).
Secondly you'll need the proprietary JenkinsRedmine plugin, see Building a plugin. The plugin actually does two simple steps:
  1. Gets all commits in fetched by Jenkins brunch issuing git log command
  2. Gets all issues in Resolved state for given project from Redmine (see Redmine REST API for Issues), checks which Issue fixed build numbers are in git log
Then it just draws a table like below. It omits issues that are not found in git log. Thus QAs get the list of issues to check on test environment.

Wednesday, August 27, 2014

Multisite with SaltStack

You have a site being deployed by SaltStack but you need to add multisiteness to it. This can mean you need to run multiple uwsgi instances (one per domain) which run wsgi app with different settings, have multiple nginx configurations, different users (one per domain) etc, etc. The problem is you cannot simply include nginx or uwsgi formula twice with different parameters just because salt doesn't support it. One has following options:
  1. Use loops in jinja templates. But every formula needs to support it, pillar data is complicated is this case
  2. Use multiple salt-minion instances (one per domain), see minionswarm.py on how to implement this. Most appealing if you need to setup on one node unrelated components, for instance, web service and database, minion in this case corresponds to the component but not to the node
  3. Use grains in pillar templates to change pillar data according to grains data, see Role-based infrastructure. Best for multisites because they differ a little
Pillar data example:
{% set site_id = grains['site_id'] %}

username: XXX
site_id: {{ site_id }}

django:
  git_url: git@XXX.git
  settings: settings_{{ site_id }}
  chdir: /home/XXX/XXX
  media_root: /home/XXX/uploads

nginx:
  server_name: {{ site_id }}.com
  media_root: /home/XXX/uploads
  media_location: /uploads

uwsgi:
  chdir: /home/XXX/XXX
  env: DJANGO_SETTINGS_MODULE=settings_{{ site_id }}
  harakiri: 90
  pythonpath: /home/XXX/XXX
And salt states doesn't change. From jenkins one can run
salt XXX grains.setval site_id site1
salt XXX state.highstate pillar="{git_rev: '$GIT_COMMIT'}"
salt XXX grains.setval site_id site2
salt XXX state.highstate pillar="{git_rev: '$GIT_COMMIT'}"
salt XXX file.blockreplace /home/XXX/static/version.txt "#-- jenkins info below this line ---" "#-- jenkins info above this line ---" "BUILD_NUMBER $BUILD_NUMBER BUILD_ID $BUILD_ID" True

Whiteboard pattern in SaltStack

The task
Imagine you have a bunch of middle-sized projects not big enough to have dedicated DevOps. These projects are pretty similar, for instance, they use either mysql or postgres, uwsgi, django, grunt or brunch for frontend, etc. The common mistake here is to let devs do the provisioning and deployment. You'll have site somehow provisioned with a bunch of child mistakes not connected to continuous integration thing with an outdated fabric script that does only deployment (updates to newer version) and one guy that knows (probably) how to setup everything from scratch.
The right way to do the job is to share one-two DevOps between projects. But in order to support 10-20 projects they need to be really effective. Fortunately there is such a thing as Salt Formulas. For instance, if all or several projects use uwsgi one can write uwsgi formula and reuse it (this is similar to code reuse: minimizes time to write and support the code).
Thus we end up with something like this. Salt states in XXX.sls:
include:
  - deploy_key
  - django
  - django.collectstatic
  - django.compilemessages
  - pil
  - django.sorl
  - mysql.client
  - nginx
  - uwsgi
  - time
  - compass
  - npm
  - grunt
  - grunt.bower
And salt pillar that configures formulas:
username: XXX

django:
  git_url: ssh://git@XXX
  settings: XXX.settings
  chdir: /home/XXX/XXX/
  requirements: /home/XXX/XXX/requirements.txt

nginx:
  server_name: 'XXX.com *.XXX.com'
  auth_basic_user_file: /home/XXX/htpasswd

uwsgi:
  chdir: /home/XXX/XXX/
  env: DJANGO_SETTINGS_MODULE=XXX.settings

compass:
  compass_version: 1.0.0.alpha.19
  sass_version: 3.3.6

npm:
  chdir: /home/XXX/XXX/frontend

grunt:
  chdir: /home/XXX/XXX/frontend
And this is almost enough to automatically deploy project XXX with SaltStack having all those formulas written beforehand. Adding a new project means gathering (with include) and configuring formulas and sometimes write new ones.
But here comes the problem. Some formulas depend on other formulas and one needs to enforce the right order of execution. For instance, uwsgi service needs to watch changes in source, thus one need to append to XXX.sls something like
extend:
  uwsgi_service:
    service:
      - watch:
        - git: source
Cons. First of all you'll need to write this in every project that uses uwsgi formula. Secondly this breaks encapsulation: this information belongs to the formula itself and may not be exposed, in case something changes in the formula you'll need to change/test ALL projects's using it.

The solution
We'll use White-board pattern that is common to devs working in OSGi/Spring world. See OSGI White-Board pattern with a sample. Imagine you need some job A to be done, you do not know who can do this and you simply put an advertisement on whiteboard (service registry) that you need someone to do this job A (need some service that implements interface A). From the other side someone who is looking for the job and can do A, B and C (implements interfaces A, B and C) puts an advertisement on whiteboard what he cans. OSGi does the rest. With SaltStack one can do the same. In our example uwsgi formula knows that it needs source code to be present and restart upon its changes. Thus the formula declares this dependency, excerpt from uwsgi/init.sls:
uwsgi_service:
  service.running:
    - name: {{ uwsgi.service }}
    - watch:
      - file: {{ uwsgi.ini }}
      - git: source
    - require:
      - file: /etc/init/{{ uwsgi.service }}.conf
      - pip: uwsgi
Uwsgi formula doesn't know who provides the sources. One of formulas provides them, in our case this is django formula, excerpt from django/init.sls:
source:
  git.latest:
    - name: {{ django.git_url }}
    - rev: {{ django.git_rev }}
    - target: {{ django.target }}
    - force: true
    - user: {{ django.username }}
    - submodules: true
    - force_checkout: true
    - force_reset: true
    - require:
      - pkg: django_pkgs
Some other project can use uwsgi formula without django formula but with some other formula that implements 'git: source' state. In this way one can drastically decrease amount of explicit dependencies. But of course beware making a lot of contracts between formulas, this will complicate their standalone usage and influence resulting flexibility. Thus we'll keep some deps in XXX.sls that are unique to this project.
The resulting XXX.sls:
include:
  - deploy_key
  - django
  - django.collectstatic
  - django.compilemessages
  - pil
  - django.sorl
  - mysql.client
  - nginx
  - uwsgi
  - time
  - compass
  - npm
  - grunt
  - grunt.bower

extend:
  django_prerequisites:
    cmd:
      - watch:
        - file: local_settings.py
      - require:
        - cmd: mysql_db
  uwsgi_service:
    service:
      - watch:
        - file: local_settings.py
  collectstatic:
    cmd:
      - require:
        - cmd: grunt
  grunt:
    cmd:
      - require:
        - gem: compass

{% from "django/map.jinja" import django with context %}

local_settings.py:
  file.managed:
    - name: {{ django.chdir }}/XXX/local_settings.py
    - source: salt://XXX/local_settings.py
    - mode: 644
    - user: {{ django.username }}
    - group: {{ django.username }}

mysql_db:
  cmd.run:
    - name: {{ django.virtualenv }}/bin/python manage.py syncdb --noinput --settings={{ django.settings }} && {{ django.virtualenv }}/bin/python manage.py migrate --delete-ghost-migrations --settings={{ django.settings }}
    - user: {{ django.username }}
    - cwd: {{ django.chdir }}
    - require:
      - virtualenv: virtualenv
      - file: local_settings.py
      - git: source

htpasswd:
  file.managed:
    - name: {{ django.home }}/htpasswd
    - source: salt://XXX/htpasswd
    - mode: 644
    - user: {{ django.username }}
    - group: {{ django.username }}
And yes, you'll need only 63 lines of code (+26 lines of pillar configuration) to deploy django, pil, solr, mysql, nginx, uwsgi, compile frontend with grunt/compass, collect static files, compile messages for translations, etc.

Friday, January 31, 2014

OSGi based web applications

OSGi attracts a lot nowadays but being a well spread technology for lightweight embedded systems and such things as Eclipse, Glassfish, etc. it is not so well spread in enterprise scenarios (despite existence of OSGi Enterprise Specification, but I've still heard success story about Apache Karaf production usage). OSGi as it breaks your application into modules and provides service registry and event bus is a right way to maintain medium to huge codebase and overcome issues with integration in big distributed teams. Live code and configuration updates support is what must have if you want availability. See beautiful article Why OSGi service dynamics are useful.
The question I was wondering recently is there a good web application framework that plays nice with OSGi (something like JSF in Java EE or Spring MVC). I found the answer on stackoverflow:
I'm developing OSGi based web applications on a daily base. We have a slightly alternative approach which works very well:
  1. RESTful web services implemented using OSGi services 
  2. Modular AngularJS based user interface, packaged in OSGi bundles Although AngularJS is obviously not a Java web framework, it fits modern web development perfectly. If you are familiar with Java MVC web frameworks it's also easy to understand Angular.
The main question is how to modularize your code. At the backend we implement everything as OSGi services. RESTful webservices are implemented with JAX-RS using the Amdatu (amdatu.org). With Amdatu you can use JAX-RS in a way that fits OSGi well. Each RESTful resource and lower level services are packaged in separate bundles as well, so the backend is fully modular.
To modularize the UI itself we separate functional different parts of the application as different Angular applications. Each Angular application is packaged in separate bundles as well, using the Amdatu resource provider.
The idea is a good one regardless OSGi part. If you are about to build a web app consider providing just REST endpoint and put on top of it something like AngularJS/Backbone/Knockout. And providing REST endpoint itself is a simple task with amdatu-web.

Sunday, January 12, 2014

Tuesday, January 7, 2014

Inversion of Control for 6 year old

If you can't explain it to a six year old, you don't understand it yourself. (Albert Einstein)
Despite release 1.0 of Spring was in 2003 the new wave of programmers seem to misuse the concept. Below we'll consider a small example to explain.