# -*- mode: org; mode: auto-fill; -*- #+STARTUP: showeverything * Org Converge [[https://secure.travis-ci.org/wallyqs/org-converge.png?branch=master]] ** Description This attempts to be an experiment of using Org mode syntax to create documentable reproducible runs, borrowing some ideas of what is possible to do with tools like =chef-solo=, =rake=, =foreman=, etc... ** Installing : gem install org-converge ** Motivation The Org babel syntax has proven to be flexible enough to writing /reproducible research/ papers. Then, I believe that configuring and setting up a server for example is something that could be also be done using the same syntax, given that /converging/ the configuration is something that one ought to be able to reproduce. ** Usage To run the blocks in parallel... #+begin_src sh org-converge path/to/setup-file.org --runmode=parallel #+end_src or sequentially... #+begin_src sh org-converge path/to/setup-file.org --runmode=sequential #+end_src By including ~:after~ or ~:before~ arguments to a block, it is possible to make the blocks depend on one another. #+begin_src sh org-converge path/to/setup-file.org --runmode=chained #+end_src *** Other commands available : org-run # alias for org-converge : org-tangle # just tangles the contents without running the blocks ** Quick example The following is an example of running 3 processes in parallel by defining them as code blocks from an Org mode file: #+begin_src sh ,#+TITLE: Running Org babel processes in parallel ,* Print with different languages   ,#+name: hello_from_bash ,#+begin_src sh :shebang #!/bin/bash while true; do echo "hello world from bash"; sleep 1; done ,#+end_src   ,#+name: hello_from_ruby ,#+begin_src ruby :shebang #!/usr/local/bin/ruby $stdout.sync = true loop { puts "hello world from ruby" ; sleep 1 } ,#+end_src   ,#+name: hello_from_python ,#+begin_src python :shebang #!/usr/bin/python import time import sys for i in range(0,100): print "hello world from python" sys.stdout.flush() time.sleep(1) ,#+end_src #+end_src We store this in a file named =hello.org= and then run it as follows: #+begin_src sh org-converge hello.org #+end_src This would produce an output similar to the following: #+begin_src sh [2014-05-04T19:23:40 +0900] Tangling 0 files... [2014-05-04T19:23:40 +0900] Tangling succeeded! [2014-05-04T19:23:40 +0900] Tangling 3 scripts within directory: /Users/mariko/repos/org-converge/run... [2014-05-04T19:23:40 +0900] Running code blocks now! (3 runnable blocks found in total) [2014-05-04T19:23:40 +0900] hello_from_bash (4664) -- started with pid 4664 [2014-05-04T19:23:40 +0900] hello_from_ruby (4665) -- started with pid 4665 [2014-05-04T19:23:40 +0900] hello_from_python (4666) -- started with pid 4666 [2014-05-04T19:23:40 +0900] hello_from_bash (4664) -- hello world from bash [2014-05-04T19:23:41 +0900] hello_from_ruby (4665) -- hello world from ruby [2014-05-04T19:23:41 +0900] hello_from_python (4666) -- hello world from python [2014-05-04T19:23:42 +0900] hello_from_ruby (4665) -- hello world from ruby #+end_src ** How it works Org Converge uses an liberally extended version of Org Babel features in order to give support for converging the configuration of a server. For example, using Org Babel and macros we can easily spread config files on a server by writing the following on a ~server.org~ file. #+begin_src sh ,#+begin_src yaml :tangle /etc/component.yml multitenant: false status_port: 10004 ,#+end_src #+end_src And then configure it by running it as follows, (considering we have the correct permissions for tangling at =/etc/component.yml=): #+begin_src sh sudo org-converge server.org #+end_src Next, let's say that we no only one want to set the configured templates, but that we also want to install some packages. In that case, we should be able to do the following: #+begin_src sh ,* Configuring the component ,#+begin_src yaml :tangle /etc/component.yml multitenant: false status_port: 10004 ,#+end_src ,* Installing the dependencies Need the following so that ~bundle install~ can compile the native extensions correctly. ,#+begin_src sh apt-get install build-essentials -y ,#+end_src   Then the following should work:   ,#+begin_src sh cd project_path bundle install ,#+end_src #+end_src ** Contributing The project is in very early development at this moment, but if you feel that it is interesting enough, please create a ticket to start the discussion.