<?xml version='1.0' encoding='UTF-8'?>
<rss version='2.0' xmlns:atom='http://www.w3.org/2005/Atom'>
<channel>
<atom:link href='http://narkisr.com/' rel='self' type='application/rss+xml'/>
<title>
Narkisr.com
</title>
<link>
http://narkisr.com/
</link>
<description>
The blog of Ronen Narkis
</description>
<lastBuildDate>
Tue, 28 Apr 2020 13:00:52 +0200
</lastBuildDate>
<generator>
clj-rss
</generator>
<item>
<guid>
http://narkisr.com/posts/27-04-2020-clara-flow/
</guid>
<link>
http://narkisr.com/posts/27-04-2020-clara-flow/
</link>
<title>
Rules, not what you recall
</title>
<description>
&lt;h3 id=&quot;intro&quot;&gt;Intro&lt;/h3&gt;&lt;p&gt;Like most developers I used to think on rule engines as a interesting technology that never took off, a common misconception around them was that they would enable domain experts to encode rules into them without the need of having developers in this process (reducing cost/implementation time).&lt;/p&gt;&lt;p&gt;As expected this never worked in practice and as projects failed interest dwindled and they were left as an historical relic together with &lt;a href='https://en.wikipedia.org/wiki/Visual_programming_language'&gt;visual programming&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;In this post I will try to revive the interest in using a rule engine and cover how I use &lt;a href='https://github.com/cerner/clara-rules'&gt;Clara rules&lt;/a&gt; in an interesting domain - operation flow automation.&lt;/p&gt;&lt;h3 id=&quot;so&amp;#95;what&amp;#95;are&amp;#95;rule&amp;#95;engines?&quot;&gt;So what are rule engines?&lt;/h3&gt;&lt;p&gt;A Rule engine include 3 main types of components:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Facts, information that our system get from the world.&lt;/li&gt;&lt;li&gt;Rules, how those facts effect our world&lt;/li&gt;&lt;li&gt;Queries that we may run in order to find what kind of rules were activate and why.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The underlying implementation uses a directed acyclic graph and an algorithm named &lt;a href='https://en.wikipedia.org/wiki/Rete_algorithm'&gt;RETE&lt;/a&gt; for efficient computation on top of a large sets of rules and facts.&lt;/p&gt;&lt;p&gt;&lt;small&gt; * If the above rings a bell of Logic programming and expert system you are not mistaken with the later usually being implemented in Prolog.&lt;/small&gt;&lt;/p&gt;&lt;p&gt;A basic rule in Clara is composed from a left hand side (a match on facts) and the right hand side (the effect of a match) separated by '=&gt;', in this case we match on facts that have a :state value of ::start :&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;ns foo&amp;#41;

&amp;#40;defrule example
  &amp;quot;An example rule&amp;quot;
  ; What to match on
  &amp;#91;?e &amp;lt;- ::start&amp;#93;
  =&amp;gt;
  ; The effect of the match
  &amp;#40;println &amp;quot;foo&amp;quot;&amp;#41;
  &amp;#40;insert! {:state ::done :failure false}&amp;#41;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Lets note a couple of interesting points here:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The RHS doesn't have to be side effect free! (see that lovely println)&lt;/li&gt;&lt;li&gt;The RHS can insert new facts into the system.&lt;/li&gt;&lt;li&gt;We can capture the incoming matched fact in variables (?e), this allows us to pass in arbitrary information to the rules.&lt;/li&gt;&lt;li&gt;Our facts are plain old Clojure maps (we can create them from any arbitrary input).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Our rule engine state (RETE remember?) is an immutable data structure (&lt;a href='https://en.wikipedia.org/wiki/Turtles_all_the_way_down'&gt;turtles&lt;/a&gt; all the way down) that we store in an atom:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;defn initialize &amp;#91;&amp;#93;
  &amp;#40;atom &amp;#40;mk-session 'foo&amp;#41;&amp;#41;&amp;#41;

&amp;#40;def session &amp;#40;initialize&amp;#41;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If we want to insert new facts into it (while keeping our old view of the world) we can just reset it:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;defn update- &amp;#91;facts&amp;#93;
  &amp;#40;let &amp;#91;new-facts &amp;#40;reduce &amp;#40;fn &amp;#91;s fact&amp;#93; &amp;#40;insert s fact&amp;#41;&amp;#41; @session facts&amp;#41;&amp;#93;
    &amp;#40;reset! session &amp;#40;fire-rules new-facts&amp;#41;&amp;#41;&amp;#41;&amp;#41;

&amp;#40;commment
  ; update our view of the world
  &amp;#40;update- {:state :foo/start :yet :another :key 1}&amp;#41;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can also query our session and ask what happened:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;defquery get-failures
  &amp;quot;Find all failures&amp;quot;
  &amp;#91;&amp;#93;
  &amp;#91;?f &amp;lt;- :re-flow.core/state &amp;#40;= true &amp;#40;this :failure&amp;#41;&amp;#41;&amp;#93;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;existing&amp;#95;approaches&quot;&gt;Existing approaches&lt;/h2&gt;&lt;p&gt;Lets take a step back and cover what a conditional is composed out of:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A predicate (the when of an IF statement).&lt;/li&gt;&lt;li&gt;The result of a match on a predict (the logic that happens after a match).&lt;/li&gt;&lt;li&gt;The computation flow (the cause and effect graph).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;We use conditional logic when we try to describe the flow of steps in a distributed process like  for example a remote backup restore test:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Create a VM with a volume to restore our data to&lt;/li&gt;&lt;li&gt;Provision the VM with the required tooling and prepare our volume&lt;/li&gt;&lt;li&gt;Check that we are ready to start the restore process (our VM is ready and our volume has the correct size)&lt;/li&gt;&lt;li&gt;Restore the data and verify that it was successful&lt;/li&gt;&lt;li&gt;Notify on success or failure&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;There are a number of ways to model this kind of flow, the simplest one is to use conditionals:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;defn restore-backup &amp;#91;backup&amp;#93;
  &amp;#40;let &amp;#91;{:keys &amp;#91;created?&amp;#93; :as creation-result} &amp;#40;create-vm&amp;#41;&amp;#93;
     &amp;#40;if-not vm-create?
         &amp;#40;throw &amp;#40;ex-info &amp;quot;failed to create the VM&amp;quot; creation-result&amp;#41;&amp;#41;
         &amp;#40;let &amp;#91;{:keys &amp;#91;provisioned?&amp;#93; :as provisioning-result} &amp;#40;provision&amp;#41;&amp;#93;
            ; rest of the flow
            &amp;#41;&amp;#41;&amp;#41;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There are a number of issue with this approch:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;As &lt;a href='https://en.wikipedia.org/wiki/Cyclomatic_complexity'&gt;Cyclomatic complexity&lt;/a&gt; explodes its really hard to reason about the code.&lt;/li&gt;&lt;li&gt;Composition is challenging since trying to compose one chain of conditional logic with another is fragile.&lt;/li&gt;&lt;li&gt;The only way to understand failure points in the code is by painstaking debugging and printing.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Another approach is to use finite state machines (FSM for short), the following FSM has a :start state and a number of transitions defined:&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;defsm restore
  &amp;#91;&amp;#91;:start
    ::create -&amp;gt; &amp;#40;create-vm&amp;#41;&amp;#93;
   &amp;#91;:created
    true -&amp;gt;  &amp;#40;provision&amp;#41;
    false -&amp;gt; &amp;#40;report-error&amp;#41;&amp;#93;
   &amp;#91;:provisioned
    true -&amp;gt;  &amp;#40;restore&amp;#41;
    false -&amp;gt; &amp;#40;report-error&amp;#41;&amp;#93;
  &amp;#91;:restored
    true -&amp;gt;  &amp;#40;printrln &amp;quot;success&amp;quot;&amp;#41;
    false -&amp;gt; &amp;#40;report-error&amp;#41;&amp;#93;
   &amp;#93;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;On a first glance this looks promising as it frees us from the conditional nesting but there are still a number of issues:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Location information is still complected making change in a large set of FMS's is still tricky.&lt;/li&gt;&lt;li&gt;They are not easy to compose (think about combining the restore FSM with a new notification FSM)&lt;/li&gt;&lt;li&gt;They lack introspection (understand why we reached a certain state within them).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;There are other approaches that solve the same problem but I would like to claim (while not providing a rigorous mathematical proof) that they are &lt;a href=&quot;https://en.wikipedia.org/wiki/Reduction_(complexity)&quot;&gt;reducible &lt;/a&gt; to the two approaches mentioned above.&lt;/p&gt;&lt;h3 id=&quot;the&amp;#95;case&amp;#95;fore&amp;#95;clara&amp;#95;rules&quot;&gt;The case fore Clara rules&lt;/h3&gt;&lt;p&gt;Coming back to the same problem space (restoration flow) our code now is composed out of a two sets of rules, the first one is the creation and provisioning logic:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;ns re-flow.setup
  ;...
  &amp;#41;

&amp;#40;defrule creating
  &amp;quot;Create VM&amp;quot;
  &amp;#91;?e &amp;lt;- ::creating &amp;#91;&amp;#93;&amp;#93;
  =&amp;gt;
  &amp;#40;insert! &amp;#40;assoc ?e :state ::created :failure &amp;#40;create-vm&amp;#41;&amp;#41;&amp;#41;


&amp;#40;defrule provisioning
  &amp;quot;Provisioning&amp;quot;
  &amp;#91;?e &amp;lt;- ::created &amp;#40;= ?failure false&amp;#41;&amp;#93;
  =&amp;gt;
   ; ....
   &amp;#40;info &amp;quot;provisioning&amp;quot;&amp;#41;
   &amp;#40;insert! &amp;#40;assoc ?e :state ::provisioned :failure &amp;#40;provision&amp;#41;&amp;#41;&amp;#41;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that we didn't specify the order of execution we only provided the predicate and the effect of a match.&lt;/p&gt;&lt;p&gt;Our restoration logic is completely decoupled from the creation logic (it resides in a different namespace), it does not care on how the instance is coming to life it only concern itself with what it should do once its up and running:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;ns re-flow.restore
  ;...
  &amp;#41;

&amp;#40;defrule check
  &amp;quot;Check that the ?e fact is matching the ::restore spec&amp;quot;
  &amp;#91;?e &amp;lt;- ::start&amp;#93;
  =&amp;gt;
  &amp;#40;insert! &amp;#40;assoc ?e :state ::spec :failure &amp;#40;not &amp;#40;s/valid? ::restore ?e&amp;#41;&amp;#41;&amp;#41;&amp;#41;&amp;#41;

&amp;#40;defrule create
  &amp;quot;Triggering the creation of the instance&amp;quot;
  &amp;#91;?e &amp;lt;- ::spec &amp;#91;{:keys &amp;#91;failure&amp;#93;}&amp;#93; &amp;#40;= failure false&amp;#41;&amp;#93;
  =&amp;gt;
  &amp;#40;info &amp;quot;Starting to run setup instance&amp;quot;&amp;#41;
  &amp;#40;insert!  &amp;#40;assoc ?e :state :re-flow.setup/creating :spec instance&amp;#41;&amp;#41;&amp;#41;

&amp;#40;defrule restore
  &amp;quot;Restoring information&amp;quot;
  &amp;#91;?e &amp;lt;- ::provisioned &amp;#91;{:keys &amp;#91;failure&amp;#93;}&amp;#93; &amp;#40;= failure false&amp;#41;&amp;#93;
  =&amp;gt;
  &amp;#40;insert! &amp;#40;assoc ?e :state ::restored :failure &amp;#40;restore&amp;#41;&amp;#41;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The check rule matches on the ::start state fact where ?e is captured and verified against a spec, the second rule trigger the creation flow if the ::spec fact failure value is false.&lt;/p&gt;&lt;p&gt;In order to launch this flow we insert a fact into our session:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;; We provide the backup information as a map within the fact
&amp;#40;update- {:state :re-flow.restore/start :backup {:source &amp;quot;s3://&amp;quot; ...}&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We may use the query we already defined to find what rule fail:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;defn run-query &amp;#91;q&amp;#93;
  &amp;#40;query @session q&amp;#41;&amp;#41;

; The query result is a native Clojure datastucture
&amp;#40;run-query get-failures&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This approach has a number of clear advantages:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Logic is decoupled its easy to make changes to one rule without breaking other rules.&lt;/li&gt;&lt;li&gt;Composition is easy, one set of rules can trigger other rules from other namespaces.&lt;/li&gt;&lt;li&gt;Tracking failure and other information is easy (just write queries)&lt;/li&gt;&lt;li&gt;We get the execution engine for free (computation graph).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;A number of other key points that we should cover:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The engine does not deal with concurrency however its immutable which allows us to set the new engine state using native Clojure Refs.&lt;/li&gt;&lt;li&gt;The Rules are not persisted to disk by default if we choose to do so we can serialize its state and persist it.&lt;/li&gt;&lt;li&gt;The engine state is not a distributed data structure, if we have multiple JVM's we can shard our facts based on keys (think Kafka consumers).&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;&lt;p&gt;Iv found Clara rules to be a really powerful tool for automation if you are curious check &lt;a href='https://github.com/re-ops/re-core/tree/master/src/re_flow'&gt;Re-core&lt;/a&gt; code, ill conclude this post with my own variation on Greenspuns tenth &lt;a href='https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule'&gt;rule&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&quot;Every complex yml/json that describes a complex pipeline is interpreted by an ad hoc informally-specified, bug-ridden, slow implementation of a Forward-chaining rules engine&quot;&lt;/p&gt;&lt;p&gt;  Pipelines are computation graphs&lt;/p&gt;&lt;h4 id=&quot;footnotes:&quot;&gt;Footnotes:&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;small&gt;Martin fowler mentioning the &lt;a href='https://martinfowler.com/bliki/RulesEngine.html'&gt;misconception&lt;/a&gt;.&lt;/small&gt;&lt;/li&gt;&lt;li&gt;&lt;small&gt;The connection between Expert &lt;a href='https://en.wikipedia.org/wiki/Expert_system'&gt;systems&lt;/a&gt; and rule engines.&lt;/small&gt;&lt;/li&gt;&lt;/ul&gt;
</description>
<pubDate>
Mon, 27 Apr 2020 00:00:00 +0200
</pubDate>
</item>
<item>
<guid>
http://narkisr.com/posts/20-02-2018-wacky/
</guid>
<link>
http://narkisr.com/posts/20-02-2018-wacky/
</link>
<title>
Speculative execution
</title>
<description>
&lt;h3 id=&quot;intro&quot;&gt;Intro&lt;/h3&gt;&lt;p&gt;One of the characteristics of good tools is that they allow creative exploration of ideas, in this post ill cover some speculative flows that Re-ops may support in the future.&lt;/p&gt;&lt;p&gt;The flows are not implemented but Re-ops makes them all possible due to its basic architecture and design.&lt;/p&gt;&lt;h2 id=&quot;voice&amp;#95;up&quot;&gt;Voice up&lt;/h2&gt;&lt;p&gt;There are a lot of cases where it makes sense to create/start a VM/Physical machine, lets take for example your media server, or a remote development machine, we need those only on specific times yet we usually run them 24/7, but what if we could trigger them based on our needs?&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;defn plex-on &amp;#91;&amp;#93;
  &amp;#40;run &amp;#40;start&amp;#41; | &amp;#40;alexa :reply &amp;quot;ok&amp;quot;&amp;#41;&amp;#41;&amp;#41;

&amp;#40;defn update-all &amp;#91;&amp;#93;
  &amp;#40;run &amp;#40;update&amp;#41; | &amp;#40;alexa :reply &amp;quot;ok&amp;quot;&amp;#41;&amp;#41;

; start VM instances by saying 'Alexa start plex on'
&amp;#40;wemo &amp;#40;alexa :event &amp;quot;plex power on&amp;quot;&amp;#41; &amp;#40;plex-on&amp;#41;&amp;#41;

; updating all the machine by saying 'Alexa update all'
&amp;#40;wemo &amp;#40;alexa :event &amp;quot;update all&amp;quot;&amp;#41; &amp;#40;update-all&amp;#41;&amp;#41;

&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now this flow isn't implemented now, I suspect it should pretty easy to implement by exposing a WeMO like interface and pretending to be one or more devices.&lt;/p&gt;&lt;p&gt;Another good options (tough it will require a bit more setup) is to use MQTT, the main issue here is exposing the MQTT broker to Alexa.&lt;/p&gt;&lt;h2 id=&quot;sensors&quot;&gt;Sensors&lt;/h2&gt;&lt;p&gt;Another cool idea is to integrate Re-ops with sensors:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;; our closet instances &amp;#40;including the physical hypervisor big-iron&amp;#41;
&amp;#40;def closet &amp;#40;Hosts. {} &amp;#91;&amp;quot;foo&amp;quot; &amp;quot;bar&amp;quot; &amp;quot;big-iron&amp;quot;&amp;#93;&amp;#41;&amp;#41;

; Stopping our closet instances when it gets too hot &amp;#40;beyond 70c&amp;#41;
&amp;#40;def check-temp &amp;#91;t&amp;#93;
  &amp;#40;when &amp;#40;&amp;gt; t 70&amp;#41;
    &amp;#40;run &amp;#40;stop hs&amp;#41; | &amp;#40;email to-from &amp;quot;stopped all closed instances, room too hot&amp;quot;&amp;#41;&amp;#41;

&amp;#40;watch :temp once-an-hour &amp;#40;check-temp &amp;#40;sensor :temperture&amp;#41;&amp;#41;

&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here we would stop all the VM's and the hosts if our server room (aka our closet) gets too hot thus preventing hardware meltdown while we are not near, we would need to exposing an MQTT end point and the rest should be pretty easy to follow.&lt;/p&gt;&lt;p&gt;A more far out scenario is automating our machines based on sensor detecting power output from solar panels (is it sunny enough or not) if there isn't enough power draw we would rather not to use costly energy from the wall, our mining farm will start/stop based on the power costs:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;; our mining instances &amp;#40;including the hypervisor big-iron&amp;#41;
&amp;#40;def mining-pool &amp;#40;Hosts. {} &amp;#91;&amp;quot;coin-1&amp;quot; &amp;quot;coin-1&amp;quot; &amp;quot;big-iron&amp;quot;&amp;#93;&amp;#41;&amp;#41;

; We produce more then 10KW of power lets start mining
&amp;#40;defn power-ok &amp;#91;&amp;#93;
   &amp;#40;run &amp;#40;start mining-pool&amp;#41; | &amp;#40;pretty &amp;quot;pool resumed&amp;quot;&amp;#41;&amp;#41;

; We produce less then 10KW of power lets stop mining
&amp;#40;defn low-power &amp;#91;&amp;#93;
  &amp;#40;run &amp;#40;stop mining-pool&amp;#41; | &amp;#40;pretty &amp;quot;pool stopped&amp;quot;&amp;#41;&amp;#41;

&amp;#40;defn adjust-pool &amp;#91;&amp;#93;
  &amp;#40;if &amp;#40;&amp;gt; &amp;#40;check-power&amp;#41; 10&amp;#41;&amp;#41;
     &amp;#40;power-ok&amp;#41;
     &amp;#40;low-power&amp;#41;&amp;#41;

&amp;#40;watch :power-check once-an-hour adjust-pool&amp;#41;

&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;scanning&quot;&gt;Scanning&lt;/h2&gt;&lt;p&gt;Running a scanning tool on a regular basis is a good way for checking compliance and detect potential security issues:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;
&amp;#40;def suspicious-ports #{25 ...}&amp;#41;
&amp;#40;def scanner &amp;#40;Hosts. {} &amp;#91;&amp;quot;scanner&amp;quot;&amp;#93;&amp;#41;&amp;#41;

&amp;#40;defn scan &amp;#91;&amp;#93;
  &amp;#40;run &amp;#40;open-ports scanner&amp;#41; | &amp;#40;pick &amp;#40;fn &amp;#91;ports&amp;#93; &amp;#40;suspicious-ports ports&amp;#41;&amp;#41;&amp;#41; | &amp;#40;email &amp;quot;suspicious ports found&amp;quot;&amp;#41;&amp;#41;

&amp;#40;watch :nmap &amp;#40;every-day 22&amp;#41; &amp;#40;scan hosts&amp;#41;&amp;#41;

&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Using the scanner from a dedicated host enables us to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Selectively allow password-less sudo access instance for the specific VM.&lt;/li&gt;&lt;li&gt;Have scanning agents running within segmented networks, thus controlling which ports/networks are exposed.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;spot&amp;#95;instances&quot;&gt;Spot instances&lt;/h2&gt;&lt;p&gt;In AWS we can bid for EC2 instances and offer a max price that we are willing to pay for them, for some workloads (like batch processing) this can be highly cost effective.&lt;/p&gt;&lt;p&gt;The main down side is that we do this bidding only within EC2, what if we could have a cost decision tree that makes a dynamic decision whether to use one provide or another:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;; some long batch job
&amp;#40;def batch &amp;#40;Hosts. {} &amp;#91;&amp;quot;worker-1&amp;quot; &amp;quot;worker-2&amp;quot; &amp;quot;master&amp;quot;&amp;#93;&amp;#41;&amp;#41;

; AWS cost per hour bellow $0.0058 per Hour
&amp;#40;defn use-ec2 &amp;#91;&amp;#93;
  &amp;#40;run &amp;#40;destroy batch&amp;#41; | &amp;#40;create batch aws-spot-instance&amp;#41;&amp;#41;&amp;#41;


; AWS too expansive we will run locally
&amp;#40;defn use-kvm &amp;#91;c&amp;#93;
  &amp;#40;run &amp;#40;destroy batch&amp;#41; | &amp;#40;create batch kvm-medium&amp;#41;&amp;#41;&amp;#41;

&amp;#40;defn pick &amp;#91;&amp;#93;
   &amp;#40;if &amp;#40;&amp;lt; &amp;#40;cost :ec2-cost&amp;#41; 0.0058&amp;#41;
     &amp;#40;use-ec2&amp;#41;
     &amp;#40;use-kvm&amp;#41;&amp;#41;&amp;#41;

; The cost changes will be collected once an hour so we won't flap too often.
&amp;#40;watch :aws-spots once-an-hour pick&amp;#41;

&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;&lt;p&gt;In this post we explored some of the more speculative (yet possible) flows that Re-ops can enable, having a flexible and fully programmable tool can really lead to interesting ideas and implementation.&lt;/p&gt;&lt;h4 id=&quot;footnotes:&quot;&gt;Footnotes:&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;small&gt;&lt;a href='http://www.belkin.com/au/Products/home-automation/c/wemo-home-automation/'&gt;WeMo&lt;/a&gt; home automation.&lt;/small&gt;&lt;/li&gt;&lt;li&gt;&lt;small&gt;&lt;a href='http://mqtt.org/'&gt;MQTT&lt;/a&gt; protocol,&lt;/small&gt;&lt;/li&gt;&lt;li&gt;&lt;small&gt;AWS &lt;a href='https://aws.amazon.com/ec2/spot/'&gt;Spot&lt;/a&gt; instances&lt;/small&gt;&lt;/li&gt;&lt;/ul&gt;
</description>
<pubDate>
Tue, 20 Feb 2018 00:00:00 +0100
</pubDate>
</item>
<item>
<guid>
http://narkisr.com/posts/04-02-2018-types-mismatch/
</guid>
<link>
http://narkisr.com/posts/04-02-2018-types-mismatch/
</link>
<title>
When types are eating away your sanity
</title>
<description>
&lt;h3 id=&quot;intro&quot;&gt;Intro&lt;/h3&gt;&lt;p&gt;Iv been programming in Java for more than 15 years and in every project I kept seeing the same pattern:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;java&quot;&gt;public class PersonTo {
  public String name;
  public Integer age;
}

public class PersonModel {
  public String name;
  public Integer age;
  public boolean isRegistered;
}

public class ServiceA {

  public void personsService&amp;#40;String json&amp;#41;{
   PersonTo person = parse&amp;#40;json&amp;#41;;
   PersonModel model = process&amp;#40;person&amp;#41;;
   persist&amp;#40;model&amp;#41;;
  }
}

&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you lucky you have a set of conversion logic in place (iv seen a lot of duplicated code that ignores the issue and just copy and past the same logic):&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;java&quot;&gt;public class PersonToConvertor&amp;lt;PersonModel&amp;gt; {
   public PersonModel convert&amp;#40;PersonTo person&amp;#41; {
    //.. the pleasure of conversion logic
    return personModel;
   }
}
public class PersonModelConvertor&amp;lt;PersonTo&amp;gt; {
   public PersonTo convert&amp;#40;PersonModel person&amp;#41; {
    //.. the pleasure of conversion logic
    return personTo;
   }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We have a simple json -&gt; PersonTo -&gt; PersonModel conversion chain, why we have those conversions? because each part of the system expect to get the data in a certain shape and form and because its better OOP modeling.&lt;/p&gt;&lt;p&gt;Still this is a simple example and you can imagine the piles and piles of code that deals with this issue, it does not matter if your programming in Java/Haskell/Go/Elm at the end of the day slurping data into your system will cost you.&lt;/p&gt;&lt;p&gt;Not only that but if the data types/structure changes you may find yourself in a huge refactoring and moving/shaking a lot of types/methods/functions around (a ripple effect).&lt;/p&gt;&lt;p&gt;But wait, is there an alternative?&lt;/p&gt;&lt;h3 id=&quot;bringing&amp;#95;back&amp;#95;sanity&quot;&gt;Bringing back sanity&lt;/h3&gt;&lt;p&gt;As a matter of a fact there is, almost any functional dynamic language does not require such wacky conversions, we can just work on the raw data:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;defn service-a &amp;#91;json&amp;#93;
    &amp;#40;-&amp;gt; json parse process persist&amp;#41;&amp;#41;

; once parsed the person is a simple hashmap datastructure that we manipulate
&amp;#40;defn process &amp;#91;person&amp;#93;
   &amp;#40;assoc person :is-registered false&amp;#41;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Oh wait, that is too simple your cheating!, what about type checking your code? making sure that its correct and all.&lt;/p&gt;&lt;p&gt;In the words of Rich Hickey:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;And I like to ask this question: What's true of every bug found in the field? &lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;Audience reply: Someone wrote it? Audience reply: It got written. &lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;It got written. Yes. What's a more interesting fact about it? It passed the type checker. &lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;With all that in mind there are cases in which verifying structure the data between components makes sense, enter clojure.spec:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;s/def ::name string?&amp;#41;
&amp;#40;s/def ::age integer?&amp;#41;

&amp;#40;s/def ::person &amp;#40;s/keys :req &amp;#91;::name ::age&amp;#93;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This allows us to check the validity in run time and check that different parts of the system conform to the specifications of others.&lt;/p&gt;&lt;h3 id=&quot;we&amp;#95;have&amp;#95;magic&amp;#95;x&amp;#95;that&amp;#95;converts&amp;#95;our&amp;#95;types!&quot;&gt;We have magic X that converts our types!&lt;/h3&gt;&lt;p&gt;There are &quot;shorter&quot; ways of converting types, such as:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Code generation, we generate our types and convertors we don't write them manually, the business isn't generated and its bound to those multiple types increasing the maintenance cost, in addition you maintain a whole set of tools and schema so its not free.&lt;/li&gt;&lt;li&gt;Automated mapping libraries, similar to code generation you still have to maintain a huge set mapping between the types also the types themself don't go away you still have multiple types describing the same entity.&lt;/li&gt;&lt;li&gt;We work on the raw parsed data matching on the JSON:&lt;/li&gt;&lt;/ol&gt;&lt;pre&gt;&lt;code class=&quot;scala&quot;&gt;class CC&amp;#91;T&amp;#93; {
  def unapply&amp;#40;a:Option&amp;#91;Any&amp;#93;&amp;#41;:Option&amp;#91;T&amp;#93; = if &amp;#40;a.isEmpty&amp;#41; {
    None
  } else {
    Some&amp;#40;a.get.asInstanceOf&amp;#91;T&amp;#93;&amp;#41;
  }
}

object M extends CC&amp;#91;Map&amp;#91;String, Any&amp;#93;&amp;#93;
object L extends CC&amp;#91;List&amp;#91;Any&amp;#93;&amp;#93;
object S extends CC&amp;#91;String&amp;#93;
object D extends CC&amp;#91;Double&amp;#93;
object B extends CC&amp;#91;Boolean&amp;#93;

for {
  M&amp;#40;map&amp;#41; &amp;lt;- List&amp;#40;JSON.parseFull&amp;#40;jsonString&amp;#41;&amp;#41;
  L&amp;#40;languages&amp;#41; = map.get&amp;#40;&amp;quot;languages&amp;quot;&amp;#41;
  language &amp;lt;- languages
  M&amp;#40;lang&amp;#41; = Some&amp;#40;language&amp;#41;
  S&amp;#40;name&amp;#41; = lang.get&amp;#40;&amp;quot;name&amp;quot;&amp;#41;
  B&amp;#40;active&amp;#41; = lang.get&amp;#40;&amp;quot;is&amp;#95;active&amp;quot;&amp;#41;
  D&amp;#40;completeness&amp;#41; = lang.get&amp;#40;&amp;quot;completeness&amp;quot;&amp;#41;
} yield {
  &amp;#40;name, active, completeness&amp;#41;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Imagine this logic for n JSON documents in your system, it gets ugly pretty quickly.&lt;/p&gt;&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;&lt;p&gt;When using types in the context of unstructured data be aware to the trade-offs, if your system deals with a huge variety of JSON/CSV or random HTML you will be spending a lot time in juggling type conversion instead of focusing on the business logic itself.&lt;/p&gt;&lt;p&gt;Its hard to quantify but ~30% is not an exaggerated number from my experience in large Java projects, other languages with better type systems might get away with less but it still a considerable overhead.&lt;/p&gt;&lt;h4 id=&quot;footnotes:&quot;&gt;Footnotes:&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;small&gt;&lt;a href='https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/SimpleMadeEasy.md'&gt;Simple Made easy&lt;/a&gt;.&lt;/small&gt;&lt;/li&gt;&lt;li&gt;&lt;small&gt;&lt;a href='http://dozer.sourceforge.net/'&gt;Dozer&lt;/a&gt; is an example for an &quot;automated&quot; bean to bean mapping framework.&lt;/small&gt;&lt;/li&gt;&lt;li&gt;&lt;small&gt; How to parse JSON in &lt;a href='https://stackoverflow.com/questions/4170949/how-to-parse-json-in-scala-using-standard-scala-classes'&gt;Scala&lt;/a&gt; using standard Scala classes?&lt;/small&gt;&lt;/li&gt;&lt;/ul&gt;
</description>
<pubDate>
Sun, 04 Feb 2018 00:00:00 +0100
</pubDate>
</item>
<item>
<guid>
http://narkisr.com/posts/17-01-2018-dependencies/
</guid>
<link>
http://narkisr.com/posts/17-01-2018-dependencies/
</link>
<title>
The balancing game
</title>
<description>
&lt;h3 id=&quot;intro&quot;&gt;Intro&lt;/h3&gt;&lt;p&gt;Dependencies exists in multiple shapes and forms in our software, some are easy to detect while other are hidden and insidious.&lt;/p&gt;&lt;p&gt;Common to all dependencies is that they have a great effect on the systems we create, in this short post ill try to make you aware on why its crucial to manage them properly and the damage that poor management can cause.&lt;/p&gt;&lt;h3 id=&quot;where&amp;#95;can&amp;#95;we&amp;#95;find&amp;#95;them?&quot;&gt;Where can we find them?&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;In external libraries our code depends upon.&lt;/li&gt;&lt;li&gt;Services that our systems use (Databases, external API's etc..).&lt;/li&gt;&lt;li&gt;Operating system, packages its running, its kernel version etc..&lt;/li&gt;&lt;li&gt;The hardware we deploy on, the network setup.&lt;/li&gt;&lt;li&gt;People we depends upon like developers, clients, investors and of course users.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;There are many other places that dependencies creep from just stop and think about it for a second.&lt;/p&gt;&lt;h3 id=&quot;good&amp;#95;or&amp;#95;bad?&quot;&gt;Good or bad?&lt;/h3&gt;&lt;p&gt;Like most things in life it depends (pun intended), any dependency can turn into a liability in the future.&lt;/p&gt;&lt;p&gt;It can make your code harder to change, OS upgrades harder or cause security issues, that said using the right dependency can reduce the amount of work you need to do while increasing reuse and security.&lt;/p&gt;&lt;p&gt;Managing dependencies is a balancing game and a delicate one at that, it takes experience and trial and error to learn which dependencies are good and which are better to avoid.&lt;/p&gt;&lt;h3 id=&quot;do's&amp;#95;and&amp;#95;don'ts&quot;&gt;Do's and Don'ts&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Map the dependencies you have and track them under an &lt;a href='https://git-scm.com/'&gt;SCM&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Use dependency managers to manage them (create them if none exists).&lt;/li&gt;&lt;li&gt;Trim dependencies once in a while, they tend to accumulate and grow like a wild plant.&lt;/li&gt;&lt;li&gt;Keep dependencies up to date, postponing updates for too long can cause your system to stagnate (there are tools that track out of date dependencies).&lt;/li&gt;&lt;li&gt;Minimize dependencies,  sometimes its better to copy and paste a single function (assuming its self isolated) than to include a entire library.&lt;/li&gt;&lt;li&gt;Don't over minimize and re-invent stuff if it exists already &lt;a href='https://en.wikipedia.org/wiki/Not_invented_here'&gt;NIH&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;&lt;p&gt;Dependencies can really change the faith of a projects (and companies) once a dependency has set in it may be really hard to detach, be cautious and aware to both the challenge and reward that your dependencies present.&lt;/p&gt;&lt;h4 id=&quot;footnotes:&quot;&gt;Footnotes:&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;small&gt;&lt;a href='https://github.com/xsc/lein-ancient'&gt;Lein Ancient&lt;/a&gt; and &lt;a href='https://github.com/ben-manes/gradle-versions-plugin'&gt;Gradle Versions&lt;/a&gt; are tools to track and report old dependencies.&lt;/small&gt;&lt;/li&gt;&lt;li&gt;&lt;small&gt; &lt;a href='https://gradle.org/'&gt;Gradle&lt;/a&gt;, &lt;a href='https://leiningen.org/'&gt;Lein&lt;/a&gt;, &lt;a href='http://bundler.io/'&gt;Bundler&lt;/a&gt;, &lt;a href='https://github.com/pypa/pipfile'&gt;Pipefile&lt;/a&gt; are good examples of code dependency management tools.&lt;/small&gt;&lt;/li&gt;&lt;li&gt;&lt;small&gt; &lt;a href='https://wiki.debian.org/Apt'&gt;Apt&lt;/a&gt;, &lt;a href='https://fedoraproject.org/wiki/DNF?rd=Dnf'&gt;DNF&lt;/a&gt; and &lt;a href='https://chocolatey.org/'&gt;Chocolatey&lt;/a&gt; manage packages on a variety of OSes.&lt;/small&gt;&lt;/li&gt;&lt;li&gt;&lt;small&gt; Configuration management tools such as &lt;a href='https://puppet.com/'&gt;Puppet&lt;/a&gt; and &lt;a href='https://www.chef.io/solutions/infrastructure-automation/'&gt;Chef&lt;/a&gt; manage dependencies of deployed components.&lt;small&gt;&lt;/li&gt;&lt;/ul&gt;
</description>
<pubDate>
Wed, 17 Jan 2018 00:00:00 +0100
</pubDate>
</item>
<item>
<guid>
http://narkisr.com/posts/16-04-2016-pi-crypt/
</guid>
<link>
http://narkisr.com/posts/16-04-2016-pi-crypt/
</link>
<title>
PI crypt
</title>
<description>
&lt;h3 id=&quot;intro&quot;&gt;Intro&lt;/h3&gt;&lt;p&gt;Raspberry PI devices are on the rage now, they are cheap portable and run Linux, using such a device on a remote site (be it for remote backup or pentesting) requires you to keep sensitive data on remote sdcards/USB drives etc.&lt;/p&gt;&lt;p&gt;In this post ill cover how to setup root encrypted RPi.&lt;/p&gt;&lt;h3 id=&quot;setup&quot;&gt;Setup&lt;/h3&gt;&lt;p&gt;Iv used a lot of resources (see footnotes) and posts in order to get a working solution using Ubuntu 15.10 as the host and Raspbian &lt;a href='https://www.raspberrypi.org/downloads/raspbian/'&gt;Jessie lite&lt;/a&gt; as the Pi OS image.&lt;/p&gt;&lt;p&gt;First we will setup the sdcard:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;# prepare the image
$ wget https://downloads.raspberrypi.org/raspbian&amp;#95;lite&amp;#95;latest
$ unzip raspbian&amp;#95;lite&amp;#95;latest
# we assume the sdcard 
$ dd if=2016-03-18-raspbian-jessie-lite.img of=/dev/sdb bs=4M
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Entering the chroot:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ aptitude install qemu-user-static
# chrooting mostly same as in kali
$ mkdir -p /mnt/chroot/boot
$ mount /dev/sdb2 /mnt/chroot/
$ mount /dev/sdb1 /mnt/chroot/boot/
$ mount -t proc none /mnt/chroot/proc
$ mount -t sysfs none /mnt/chroot/sys
$ mount -o bind /dev /mnt/chroot/dev
$ mount -o bind /dev/pts /mnt/chroot/dev/pts
$ cp /usr/bin/qemu-arm-static /mnt/chroot/usr/bin/
# And we are home
$ LANG=C chroot /mnt/chroot/
$ uname -a
 Linux foo 4.2.0-25-generic #30-Ubuntu SMP Mon Jan 18 12:31:50 UTC 2016 armv7l GNU/Linux
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Setting up initramf (yes your are running arm binaries on your x86 machine):&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;# Comment out the single line in this file &amp;#40;or else apt-get wont work&amp;#41;
$ vi /etc/ld.so.preload
$ apt-get update
$ apt-get install busybox cryptsetup dropbear -y
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Our first mkinitramfs (the small dropbear that will load prior to the OS):&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;# find the kernel version for initramfs
$ ls -l /lib/modules/ |awk -F&amp;quot; &amp;quot; '{print $9}'
4.1.19+
4.1.19-v7+

# You can ignore the 'Unsupported ioctl: cmd=0x5331' at the end
$ mkinitramfs -o /boot/initramfs.gz 4.1.19-v7+
$ update-rc.d ssh enable
# set the root password for the init image
$ passwd
# Now edit and change/add root=/dev/mapper/crypt&amp;#95;sdcard cryptdevice=/dev/mmcblk0p2:crypt&amp;#95;sdcard 
$ vi /boot/cmdline.txt
# add 'initramfs initramfs.gz 0x00f00000'
$ vi /boot/config.txt
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Copy the private ssh key that will enabled you to ssh to the dropbear instance (in which you enter the decryption password):&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ cat /etc/initramfs-tools/root/.ssh/id&amp;#95;rsa
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At this point we will load modules (bypassing 'debian /sbin/cryptsetup: not found raspbian') and change the fstab to point to crypt_sdcard and:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ cat /etc/fstab
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults 0 2
/dev/mapper/crypt&amp;#95;sdcard / ext4 defaults,noatime 0 1

# make sure to load the initramfs modules 
$ cat /usr/share/initramfs-tools/modules
aes
chainiv
cryptomgr 
krng
sha256
sha224
sha512
sha1
xts
cbc
ecb
ctr
dm-crypt
dm-mod
# And yet again
$ cat /etc/initramfs-tools/modules
aes
chainiv
cryptomgr 
krng
sha256
sha224
sha512
sha1
xts
cbc
ecb
ctr
dm-crypt
dm-mod
# append the following to /usr/share/initramfs-tools/hooks/cryptroot &amp;#40;after the askpass copy&amp;#95;exec&amp;#41;:
$ cat /usr/share/initramfs-tools/hooks/cryptroot | grep /sbin/cryptsetup -A 5
copy&amp;#95;exec /sbin/cryptsetup
copy&amp;#95;exec /sbin/dmsetup
copy&amp;#95;exec /lib/cryptsetup/askpass
# new section
for mod in aes chainiv cryptomgr krng sha256 sha224 sha512 sha1 xts cbc ecb ctr dm-crypt dm-mod; do
 add&amp;#95;crypto&amp;#95;modules $mod
done

# ignore the cryptsetup errors since we don't have encryption set yet
$ mkinitramfs -o /boot/initramfs.gz 4.1.19-v7+

&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We will un-chroot and copy our work aside so we can copy it back once the drive is encrypted:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ exit
$ umount /mnt/chroot/boot
$ umount /mnt/chroot/sys
$ umount /mnt/chroot/proc
# Backup our work thus far
$ mkdir -p /mnt/backup
$ rsync -avh /mnt/chroot/&amp;#42; /mnt/backup/
# finalize the un-chrooting
$ umount /mnt/chroot/dev/pts
$ umount /mnt/chroot/dev
$ umount /mnt/chroot
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We will move to setting up the encrypted drive&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ echo -e &amp;quot;d\n2\nw&amp;quot; | fdisk /dev/sdb
# note the use of 131072 which is where sdb1 ends for this specific image
$ echo -e &amp;quot;n\np\n2\n131072\n\nw&amp;quot; | fdisk /dev/sdb
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Extrac the SDcard (so the new partitioning scheme will be detected) and move to encrypting the new partition:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ cryptsetup -v -y --cipher aes-cbc-essiv:sha256 --key-size 256 luksFormat /dev/sdb2
$ cryptsetup -v luksOpen /dev/sdb2 crypt&amp;#95;sdcard
$ mkfs.ext4 /dev/mapper/crypt&amp;#95;sdcard
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can now restore our backup into the new encrypted partition:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ mkdir -p /mnt/encrypted
$ mount /dev/mapper/crypt&amp;#95;sdcard /mnt/encrypted/
$ rsync -avh /mnt/backup/&amp;#42; /mnt/encrypted/
$ umount /mnt/encrypted/
$ rm -rf /mnt/backup
$ sync
$ cryptsetup luksClose /dev/mapper/crypt&amp;#95;sdcard
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can now insert the SDcard into the PI and carry on to logging in.&lt;/p&gt;&lt;h3 id=&quot;login&quot;&gt;Login&lt;/h3&gt;&lt;p&gt;The login process is now composed of two steps, first logging into the dropbear session and decrypt the drive, the second is the usual ssh login:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;# find the IP by viewing the pi load screen
$ ssh -i private root@&amp;lt;ip&amp;gt;
# Enter your key
$ /scripts/local-top/cryptroot
# trigger the boot process
$ kill -9 `ps | grep -m 1 'cryptroot' | cut -d ' ' -f 3`
# once the pi loads you should be able to login as usual
$ ssh pi@&amp;lt;ip&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;&lt;p&gt;The processes of setting the root encrypted image is quite contrived and manual at the moment, the guides out there aren't complete or up to date, this guide is a starting point for a more automated approach.&lt;/p&gt;&lt;h4 id=&quot;footnotes:&quot;&gt;Footnotes:&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;small&gt; The original tutorial for &lt;a href='https://www.offensive-security.com/kali-linux/raspberry-pi-luks-disk-encryption/]'&gt;Kali&lt;/a&gt; Linux which gives a good outline (doesn't work as is on Raspbian tough).&lt;/small&gt;&lt;/li&gt;&lt;li&gt;&lt;small&gt; A &lt;a href='https://hblok.net/blog/posts/2014/02/06/chroot-to-arm/'&gt;post&lt;/a&gt; which mainly helped me to solve 'qemu: uncaught target signal 4' error. &lt;/small&gt;&lt;/li&gt;&lt;li&gt;&lt;small&gt; A &lt;a href='https://www.raspberrypi.org/forums/viewtopic.php?f=66&amp;t=130268'&gt;post&lt;/a&gt; that helped solved the 'debian /sbin/cryptsetup: not found raspbian'  errors &lt;/small&gt;&lt;/li&gt;&lt;/ul&gt;
</description>
<pubDate>
Sat, 16 Apr 2016 00:00:00 +0200
</pubDate>
</item>
<item>
<guid>
http://narkisr.com/posts/27-12-2014-security-onion-vagrant/
</guid>
<link>
http://narkisr.com/posts/27-12-2014-security-onion-vagrant/
</link>
<title>
Security onion vagrant
</title>
<description>
&lt;h3 id=&quot;intro&quot;&gt;Intro&lt;/h3&gt;&lt;p&gt;Setting up &lt;a href='http://en.wikipedia.org/wiki/Intrusion_detection_system'&gt;IDS&lt;/a&gt; systems such as &lt;a href='https://www.snort.org/'&gt;snort&lt;/a&gt; has always been a tedious task, &lt;a href='http://blog.securityonion.net/p/securityonion.html'&gt;Security onion&lt;/a&gt; (or SO for short) is a solution that aims to change that.&lt;/p&gt;&lt;p&gt;It includes not only snort but also &lt;a href='http://www.ossec.net/'&gt;ossec&lt;/a&gt; (a HIDS system), &lt;a href='https://code.google.com/p/enterprise-log-search-and-archive/'&gt;ELSA&lt;/a&gt; for central logging management, &lt;a href='https://www.snorby.org/'&gt;Snorby&lt;/a&gt; a dashboard for IDS events. &lt;/p&gt;&lt;p&gt;SO publishes a &lt;a href='https://launchpad.net/~securityonion/+archive/ubuntu/stable'&gt;PPA&lt;/a&gt; which is Ubuntu 12.04 compatible and distributes a livecd &lt;a href='http://sourceforge.net/projects/security-onion/'&gt;ISO&lt;/a&gt; for setting it up on physical machines.&lt;/p&gt;&lt;p&gt;In this post ill go through on how to setup SO vagrant box, enabling us to do fast iterations and provisioning development.&lt;/p&gt;&lt;h4 id=&quot;box&amp;#95;setup&quot;&gt;BOX setup&lt;/h4&gt;&lt;p&gt;The first step is creating the SO box itself using &lt;a href='https://www.packer.io/'&gt;packer&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ git clone git://github.com/narkisr/packer-security-onion.git 
# won't work on a headless machine
$ make virtualbox/security-onion-12.04.4  
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The box itself is quite heavily customized due to the requirements of SO, once the box was created we import it like any other:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ vagrant box add security-onion-12.04.4&amp;#95;puppet-3.7.3 box/virtualbox/security-onion-12.04.4&amp;#95;puppet&amp;#95;3.7.3.box
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we are ready to start rolling vagrant.&lt;/p&gt;&lt;h4 id=&quot;vagrant&quot;&gt;Vagrant&lt;/h4&gt;&lt;p&gt;Perquisites:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='https://github.com/opskeleton/opskeleton'&gt;Opskeleton&lt;/a&gt; defines the project layout of the following Vagrant/Puppet code base so make sure to &lt;a href='https://github.com/opskeleton/opskeleton#installation'&gt;have&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;SO itself requires a running GUI (so no headless servers).&lt;/li&gt;&lt;li&gt;Have a mirror port ready on your switch connected to a physical interface (if you want to capture meaningful traffic), note that you can customize the mirror port vagrant uses (using VAGRANT_MIRROR).&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ git clone git://github.com/opskeleton/security-onion-sandbox.git
# Wont work on a headless machine
$ gem install bundle
$ bundle install
$ librarian-puppet install
# in order to customize mirror port use VAGRANT&amp;#95;MIRROR=ifc
$ vagrant up
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once the VM UI is running enter a terminal and start sosetup:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ sosetup
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On its first invocation the wizard will guide you through the network setup, choose eth0 as the management interface and eth1 as the monitor interface, reboot once done.&lt;/p&gt;&lt;p&gt;Once the machine is up run sosetup again to setup Sguil and Snorby u/p&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ sosetup
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once done you can either head on to &lt;a href='https://localhost'&gt;localhost&lt;/a&gt; (from within the VM) or from the host use the forwarded ports &lt;a href='https://localhost:8444'&gt;snorby&lt;/a&gt;.&lt;/p&gt;&lt;h4 id=&quot;footnotes:&quot;&gt;Footnotes:&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;small&gt; Sadly automating the setup wizard using Puppet didn't workout, you can pass an answer file but the text based wizard does not work proprerly while being ran from the Puppet exec call. &lt;/small&gt;&lt;/li&gt;&lt;li&gt;&lt;small&gt; openssh server didn't work well so the vagrant box is using dropbear instead.&lt;/small&gt;&lt;/li&gt;&lt;/ul&gt;
</description>
<pubDate>
Sat, 27 Dec 2014 00:00:00 +0100
</pubDate>
</item>
<item>
<guid>
http://narkisr.com/posts/18-05-2013-node-cljs/
</guid>
<link>
http://narkisr.com/posts/18-05-2013-node-cljs/
</link>
<title>
Nodifying Clojure
</title>
<description>
&lt;h2 id=&quot;intro&quot;&gt;Intro&lt;/h2&gt;&lt;p&gt;In this post ill cover how to integrate ClojureScript (cljs in short) with nodejs, the use case I was trying to solve was to write  &lt;a href='http://hubot.github.com/'&gt;hubot&lt;/a&gt;  integration script with a product Im working on.&lt;/p&gt;&lt;p&gt;Hubot scripts are written using Coffeescript but iv really missed the power of Clojure under my finger tips so iv decided to write a nodejs library with all the main logic in cljs. I wanted to have a full development stack with build, dependency management and testing support.&lt;/p&gt;&lt;p&gt;A key point to understand is that a cljs/node project is living on dual platforms at once, it has dependencies rooted in its nodejs package.json file and some in its cljs project.clj not to mention two build procedures.&lt;/p&gt;&lt;h4 id=&quot;setting&amp;#95;up:&quot;&gt;Setting up:&lt;/h4&gt;&lt;p&gt;The tool chain required in setting up a project include: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='https://github.com/technomancy/leiningen'&gt;lein&lt;/a&gt;  the Clojure build tool we will be using &lt;a href='https://github.com/emezeske/lein-cljsbuild'&gt;lein-cljsbuild&lt;/a&gt;  plugin in order to compile our cljs code.&lt;/li&gt;&lt;li&gt;&lt;a href='https://npmjs.org/'&gt;npm&lt;/a&gt;  which is the nodejs package management tool, I highly recommend using  &lt;a href='https://github.com/creationix/nvm'&gt;nvm&lt;/a&gt;  for setting it up.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The project structure includes:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;├── lib # our compiled cljs js file
├── Makefile # nodejs build tasks
├── node&amp;#95;modules # npm local libraries
├── package.json # npm dependencies
├── project.clj # lein cljs build and dependencies
├── src # cljs source
├── test # compiled test js file
└── test-cljs # cljs test code
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The project.clj contains our cljs build settings and dependencies:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;defproject celestial-node &amp;quot;0.1.0-SNAPSHOT&amp;quot;
  :description &amp;quot;Celestial nodejs integration&amp;quot;
  :url &amp;quot;https://github.com/narkisr/celestial-node&amp;quot;
  :license {:name &amp;quot;Apache V2&amp;quot; :url &amp;quot;https://www.apache.org/licenses/LICENSE-2.0.html&amp;quot;}
  :dependencies &amp;#91;&amp;#91;org.clojure/core.incubator &amp;quot;0.1.2&amp;quot;&amp;#93;
                 &amp;#91;org.bodil/redlobster &amp;quot;0.2.1&amp;quot;&amp;#93;
                 &amp;#91;litmus &amp;quot;0.2.0-SNAPSHOT&amp;quot;&amp;#93;&amp;#93;
  
  :plugins  &amp;#91;&amp;#91;lein-cljsbuild &amp;quot;0.3.0&amp;quot;&amp;#93;&amp;#93;
  
  :cljsbuild {
              :builds
              {:prod 
               {:source-paths &amp;#91;&amp;quot;src&amp;quot;&amp;#93;
                :compiler {
                           :target :nodejs
                           :output-to &amp;quot;lib/celestial.js&amp;quot;
                           :optimizations :simple
                           :pretty-print true}}
               :test
               {:source-paths &amp;#91;&amp;quot;test-cljs&amp;quot;&amp;#93;
                :compiler {
                           :target :nodejs
                           :output-to &amp;quot;test/celestial.js&amp;quot;
                           :optimizations :simple
                           :pretty-print true}}}}
  &amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Notice that there are two builds with two different outputs, one for production use (lib/celestial.js) and one for testing (test/celestial.js), this enable us to keep test logic out of our production code (in fact the test run executes as a part of the main) , in order to build the cljs output we could run:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt; # one time compilation
 $ lein cljsbuild once 
 # auto compilation on save
 $ lein cljsbuild auto
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&quot;testing:&quot;&gt;Testing:&lt;/h4&gt;&lt;p&gt;Another key aspect is a testing framework, most cljs testing frameworks deal with testing browser code (and require phantom js), the only one that iv found to run well on nodejs and has a cljs DSL is  &lt;a href='https://github.com/hsalokor/litmus'&gt;litmus&lt;/a&gt;  which wrapps around  &lt;a href='http://visionmedia.github.io/mocha/'&gt;mocha.js&lt;/a&gt; , currently its not up on Clojars so build it locally using lein install.&lt;/p&gt;&lt;p&gt;The following show cases how a litmus test looks like:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt; &amp;#40;describe &amp;quot;system manipulations&amp;quot;
   &amp;#40;given &amp;quot;we store a new system&amp;quot;  
      &amp;#40;it-async &amp;quot;creates a new id&amp;quot;    
        &amp;#40;create-system &amp;#40;slurp-edn &amp;quot;fixtures/redis-system.edn&amp;quot;&amp;#41; 
            &amp;#40;fn &amp;#91;body&amp;#93; &amp;#40;reset! sys-id &amp;#40;aget body &amp;quot;id&amp;quot;&amp;#41;&amp;#41; &amp;#40;done&amp;#41;&amp;#41;
            &amp;#40;fn &amp;#91;error&amp;#93; &amp;#40;println &amp;quot;failed&amp;quot; error&amp;#41; &amp;#40;done&amp;#41;&amp;#41;&amp;#41;&amp;#41;
      &amp;#40;it-async &amp;quot;we can fetch it back&amp;quot;
        &amp;#40;get-system @sys-id 
            &amp;#40;fn &amp;#91;body&amp;#93; &amp;#40;equals? &amp;#40;aget body &amp;quot;type&amp;quot;&amp;#41; =&amp;gt; &amp;quot;redis&amp;quot;&amp;#41; &amp;#40;done&amp;#41;&amp;#41;
            &amp;#40;fn &amp;#91;error&amp;#93; &amp;#40;println error&amp;#41;&amp;#41;&amp;#41;&amp;#41;    
          &amp;#41;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Due to the async nature of nodejs we use done fn to mark when a test is indeed done, the DSL is BDD oriented, in order to run the tests we run the 'make test' defined in our Makefile (which is a part of the nodejs build system), the Makefile consists of: &lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;REPORTER = dot
  
test:
        @NODE&amp;#95;ENV=test ./node&amp;#95;modules/.bin/mocha \
        --reporter $&amp;#40;REPORTER&amp;#41; \
        --ui tdd -t 3000
    
test-w:
        @NODE&amp;#95;ENV=test ./node&amp;#95;modules/.bin/mocha \
        --reporter $&amp;#40;REPORTER&amp;#41; \
        --growl \
        --ui tdd \
        --watch

package: clean
        lein cljsbuild once
        mkdir pkg
        cp lib/celestial.js pkg
        cp -r fixtures pkg
        
clean:  
      rm -rf pkg

.PHONY: test test-w
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you can see the test target invokes the mocha binary located under npm's node_modules library which is defined in the package.json file: &lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;javascipt&quot;&gt;{
  &amp;quot;name&amp;quot;: &amp;quot;celestial-node&amp;quot;,
  &amp;quot;preferGlobal&amp;quot;: false,
  &amp;quot;version&amp;quot;: &amp;quot;0.1.0&amp;quot;,
  &amp;quot;author&amp;quot;: &amp;quot;Ronen Narkis &amp;lt;narkisr@gmail.com&amp;gt; &amp;#40;http://narkisr.com&amp;#41;&amp;quot;,
  &amp;quot;description&amp;quot;: &amp;quot;Celestial API for nodejs&amp;quot;,
  &amp;quot;repository&amp;quot;: {
    &amp;quot;type&amp;quot;: &amp;quot;git&amp;quot;,
    &amp;quot;url&amp;quot;: &amp;quot;&amp;quot;
  },
  &amp;quot;license&amp;quot;: &amp;quot;Apache-V2&amp;quot;,
  &amp;quot;dependencies&amp;quot;: {
    &amp;quot;npm&amp;quot;: &amp;quot;&amp;gt;= 1.1.2&amp;quot;,
    &amp;quot;request&amp;quot;: &amp;quot;=2.21.0&amp;quot;
  },
  &amp;quot;scripts&amp;quot;: {
    &amp;quot;test&amp;quot;: &amp;quot;make test&amp;quot;
  },
  &amp;quot;devDependencies&amp;quot;: {
    &amp;quot;chai&amp;quot;: &amp;quot;&amp;#42;&amp;quot;,
    &amp;quot;mocha&amp;quot;: &amp;quot;&amp;#42;&amp;quot;
   },
  &amp;quot;optionalDependencies&amp;quot;: {},
  &amp;quot;engines&amp;quot;: {
    &amp;quot;node&amp;quot;: &amp;quot;0.6 || 0.7 || 0.8&amp;quot;
  },
  &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,
  &amp;quot;main&amp;quot;: &amp;quot;lib/celestial.js&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nodejs integration:&lt;/p&gt;&lt;p&gt;The package.json includes all our nodejs dependencies (remeber the duality part?), we can add and use any nodejs module from our cljs code, in order to use a nodejs module:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;; nodejs require
&amp;#40;def request &amp;#40;js/require &amp;quot;request&amp;quot;&amp;#41;&amp;#41; 

; js interop usage
&amp;#40;defn GET &amp;#91;url s f&amp;#93;
  &amp;#40;.get request &amp;#40;&amp;lt;&amp;lt; &amp;quot;&amp;#126;&amp;#40;@conf :url&amp;#41;&amp;#126;{url}&amp;quot;&amp;#41; &amp;#40;clj-&amp;gt;js &amp;#40;opts&amp;#41;&amp;#41; &amp;#40;response- s f&amp;#41;&amp;#41;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In order to expose cljs api to nodejs consumers we need to export a ns:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;ns celestial.core ...&amp;#41;
 
&amp;#40;defn main &amp;#91;&amp;#93;&amp;#41;

; required even if we don't use a main
&amp;#40;set! &amp;#42;main-cli-fn&amp;#42; main&amp;#41;

; export this ns as a part of nodejs module
&amp;#40;aset js/exports &amp;quot;core&amp;quot; celestial.core&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With that all in place we can require our cljs module from any other npm enabled project:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;javascipt&quot;&gt;{
  &amp;quot;name&amp;quot;: &amp;quot;hubot-celestial&amp;quot;,
  &amp;quot;version&amp;quot;: &amp;quot;0.0.1&amp;quot;,
  &amp;quot;description&amp;quot;: &amp;quot;Hubot script for interacting with Celestial&amp;quot;,
  &amp;quot;main&amp;quot;: &amp;quot;main.js&amp;quot;,
  &amp;quot;scripts&amp;quot;: {
  },
  &amp;quot;repository&amp;quot;: &amp;quot;git://github.com/narkisr/hubot-celestial.git&amp;quot;,
  &amp;quot;author&amp;quot;: &amp;quot;narkisr.com&amp;quot;,
  &amp;quot;license&amp;quot;: &amp;quot;Apache-V2&amp;quot;,
  &amp;quot;dependencies&amp;quot;: {
    &amp;quot;coffee-script&amp;quot;: &amp;quot;&amp;#126;1.4.0&amp;quot;,
    &amp;quot;hubot&amp;quot;: &amp;quot;&amp;#126;2.4.8&amp;quot;,
    &amp;quot;hubocator&amp;quot;: &amp;quot;0.1.2&amp;quot;,
    &amp;quot;cli-table&amp;quot; : &amp;quot;0.2.0&amp;quot;,
    &amp;quot;underscore&amp;quot; :&amp;quot;1.4.4&amp;quot;,
    &amp;quot;celestial-node&amp;quot;:&amp;quot;git://github.com/narkisr/celestial-node.git&amp;quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Requiring the api:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;javascipt&quot;&gt;celestial = require &amp;#40;'celestial-node'&amp;#41;
celestial.core.get&amp;#95;system&amp;#40;id,&amp;#40;&amp;#40;b&amp;#41;-&amp;gt; msg.send systemTable&amp;#40;b&amp;#41;&amp;#41;, &amp;#40;&amp;#40;e&amp;#41;-&amp;gt; msg.send e&amp;#41;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;&lt;p&gt;Iv found cljs and nodejs to be a very powerfull (yet a bit young) combo to work with, it offers yet another very rich platform to run Clojure code on top of. I hope you will find it useful too.&lt;/p&gt;&lt;h4 id=&quot;footnotes:&quot;&gt;Footnotes:&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='https://github.com/narkisr/celestial-node'&gt;celestial-node&lt;/a&gt; (most of the code preseted)&lt;/li&gt;&lt;li&gt;&lt;a href='https://github.com/narkisr/hubot-celestial'&gt;hubot-celestial&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
</description>
<pubDate>
Sat, 18 May 2013 00:00:00 +0200
</pubDate>
</item>
<item>
<guid>
http://narkisr.com/posts/13-04-2013-tf101-cyanogenmod/
</guid>
<link>
http://narkisr.com/posts/13-04-2013-tf101-cyanogenmod/
</link>
<title>
Asus TF101 Cyanogenmod
</title>
<description>
&lt;h3 id=&quot;intro&quot;&gt;Intro&lt;/h3&gt;&lt;p&gt;In this post ill try to cover in detail how to root your  &lt;a href='http://www.amazon.com/Transformer-TF101-A1-10-1-Inch-Tablet-Separately/dp/B004U78J1G'&gt;Asus TF101&lt;/a&gt;  device.  Some of the difficuly in rooting android devices is lack of clear undestanding of the process combbined with lack of proper documentation, I hope to clear a bit of the myst in this post. &lt;br /&gt;&lt;/p&gt;&lt;h6 id=&quot;disclaimer,&amp;#95;i&amp;#95;take&amp;#95;no&amp;#95;responsility&amp;#95;if&amp;#95;you&amp;#95;brick&amp;#95;you&amp;#95;device&amp;#95;or&amp;#95;any&amp;#95;other&amp;#95;damage&amp;#95;that&amp;#95;this&amp;#95;might&amp;#95;inflict&amp;#95;on&amp;#95;your&amp;#95;device,&amp;#95;proceed&amp;#95;at&amp;#95;your&amp;#95;own&amp;#95;peril!&quot;&gt;DISCLAIMER, I take no responsility if you brick you device or any other damage that this might inflict on your device, proceed at your own peril!&lt;/h6&gt;&lt;h4 id=&quot;scheme&quot;&gt;Scheme&lt;/h4&gt;&lt;p&gt;A root session is composed from 4 steps: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Rooting your device (basicly enabling root user access to underlying Linux system).&lt;/li&gt;&lt;li&gt;Install  ClockworkMod Recovery(http://forum.xda-developers.com/wiki/ClockworkMod_Recovery)  which is a recovery tool installed on the device, this enables unpacking of custom Android distributions on your device (like &lt;a href='http://www.cyanogenmod.org/'&gt;cyanogenmod&lt;/a&gt; &quot;).&quot;&lt;/li&gt;&lt;li&gt;Booting into CWM and installing a custom ROM from a predownloaded zip file.&lt;/li&gt;&lt;li&gt;Instaling Google aps from a pre download zip file (the reason this is required is because Google forbided the bundling of its closed source product with the custom ROM).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Lets begin with rooting the device, we will follow  &lt;a href='http://setupguides.blogspot.co.il/2013/01/easily-root-asus-tf101-transformer.html'&gt;this&lt;/a&gt;  method, first we will install adb and fastboot (both are android tools for interacting with the device) as described  &lt;a href='http://www.webupd8.org/2012/08/install-adb-and-fastboot-android-tools.html'&gt;here&lt;/a&gt; :&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ sudo add-apt-repository ppa:nilarimogard/webupd8
$ sudo apt-get update
$ sudo apt-get install android-tools-adb android-tools-fastboot
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now enable usb debbuging in your device and connect it to your pc, it should be detected by adb:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ adb devices                                                                  
List of devices attached 
xxxxxxxxxxxxxxx device
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we will download TF101_Root.zip which includes a script and blob file that will uploaded via adb &lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ wget http://ubuntuone.com/5xwKVscUxwgdnudw589ERd -O TF101&amp;#95;Root.zip
$ unzip TF101&amp;#95;Root.zip
# Now I follow root&amp;#95;tf101.sh
$ adb push recoveryblob /sdcard/
$ adb shell mv /data/local/tmp /data/local/tmp.bak
$ adb shell ln -s /dev/block/mmcblk0p4 /data/local/tmp
$ adb reboot 
# wait to device to boot before proceeding
$ adb shell dd if=/sdcard/recoveryblob of=/dev/block/mmcblk0p4
$ adb shell exit
$ adb reboot 
# wait to device to boot before proceeding
$ adb push Superuser-3.0.7-efghi-signed.zip /sdcard/
$ adb reboot 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now at the last boot follow the script maunal steps: &lt;blockquote&gt;  Shut down the Transformer manually and boot into recovery. To boot into recovery hold Power + Volume Down buttons and next confirm with Volume Up buked. Rogue XM recovery will boot.&lt;br /&gt; Select the option to wipe cache, wipe Dalvik cache, then choose Install zip file from internal storage and choose the Superuser-3.0.7-efghi-signed.zip. &lt;/blockquote&gt;&lt;/p&gt;&lt;p&gt;Congrates you have root access now.&lt;/p&gt;&lt;p&gt;Now lets head on to installing CWM, from your device download  &lt;a href='http://goo.im/devs/RaymanFX/downloads/ClockWordMod-Recovery/TF101/cwm-6.0.2.1-notouch-hybrid.zip'&gt;cwm-6.0.2.1-notouch-hybrid.zip&lt;/a&gt;  as referenced from this forum &lt;a href='' title=http://forum.xda-developers.com/showthread.php?t=1855686&gt;entry&lt;/a&gt;  , reboot into recovery mode (same as before) and apply the zip, reboot again and use the volume-up and power button to enter into CWM recovery.&lt;/p&gt;&lt;p&gt;Once you see the CWM recovery loading and working we can proceed with installing the unofficial cyanogenmod as reviewed  &lt;a href='http://forum.xda-developers.com/showthread.php?t=2010903'&gt;here&lt;/a&gt; , from within your device browser download  &lt;a href='http://goo.im/getmd5/devs/RaymanFX/downloads/CyanogenMod-10.1/TF101/v0.8.0.zip'&gt;v0.8.0.zip&lt;/a&gt;  and Google apps  &lt;a href='http://goo.im/devs/RaymanFX/downloads/Gapps/4.2_gapps-jb-20121119.zip'&gt;4.2_gapps-jb-20121119.zip&lt;/a&gt; , now boot into CWM and apply the v0.8.0.zip from internal sdcard, also clear the device and dalvik caches reboot into the new Android OS.&lt;/p&gt;&lt;p&gt;Note that it will be missing Google apps but we still need to boot into the new OS before applying the second Google apps zip, now its safe to boot into CWM and apply the 4.2_gapps-jb-20121119.zip, one last reboot and you should be greated with Google acount setup dialog.&lt;/p&gt;
</description>
<pubDate>
Sat, 13 Apr 2013 00:00:00 +0200
</pubDate>
</item>
<item>
<guid>
http://narkisr.com/posts/24-07-2012-waiting-for/
</guid>
<link>
http://narkisr.com/posts/24-07-2012-waiting-for/
</link>
<title>
Waiting for your future
</title>
<description>
&lt;p&gt; So, you've got an action that you want to run in parallel using multiple cores, in pure Java land you have the old fashioned Thread.start which takes a Runnable implementation, another option is the  &lt;a href='http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html'&gt;ExecutorService&lt;/a&gt;  which uses a pool to store a collection of reusable threads (in fact its the same pool that agents use).  Clojure on the other hand has the  &lt;a href='http://clojuredocs.org/clojure_core/clojure.core/future'&gt;future&lt;/a&gt;  macro which takes a body of code and runs it on a seprate thread:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;def f &amp;#40;future &amp;#40;println &amp;quot;hello&amp;quot;&amp;#41;&amp;#41;&amp;#41;
  
@f ; will block here until it executes 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Futures use an unbound thread pool which is good for IO bound actions, lets assume we have a sequence (a large one at that) that serves as an input to that heavy IO operation, we want to parallelize the operation on multiple cores, the naive approach will be:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt; &amp;#40;defn action &amp;#91;i&amp;#93;
    &amp;#40;Thread/sleep 4000&amp;#41;
    &amp;#40;println i&amp;#41;&amp;#41;

&amp;#40;defn -main &amp;#91;&amp;#93;
  &amp;#40;map &amp;#40;future &amp;#40;action %&amp;#41;&amp;#41; &amp;#40;range 1000&amp;#41;&amp;#41;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Running this code will result with no future run, the main thread will exit before any future gets the chance to execute (since its async), in order to wait for them to run we need to deref all futures,&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt; &amp;#40;defn -main &amp;#91;&amp;#93;
  &amp;#40;map deref &amp;#40;map &amp;#40;future &amp;#40;action %&amp;#41;&amp;#41; &amp;#40;range 1000&amp;#41;&amp;#41;&amp;#41;&amp;#41; 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This looks good and indeed when we run it we notice the following output&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;0
1 
.. ; omitted for brevity 
.. 
31
nil nil nil  ; after a delay 
32
..
..
63 ; order is random 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So whats going on here? we a get a lot less concurrency then we'd like, what we see here is Clojure chunking in action, since the inner map is lazy we produce 32 futures in each chunk deref them and carry on to the next, we could force all futures by using doall:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;defn -main &amp;#91;&amp;#93;
  &amp;#40;map deref &amp;#40;doall &amp;#40;map &amp;#40;future &amp;#40;action %&amp;#41;&amp;#41; &amp;#40;range 1000&amp;#41;&amp;#41;&amp;#41;&amp;#41;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This poses another problem, we issue 1000 future and hammer on, this might cause the IO target to grind into a halt (be it filesystem or remote web service), a more controled method is required.  One option is to use Java's own ExecutorService and submit actions into that (using a bounded pool) and in fact thats exactly what &lt;a href='https://github.com/pallet/pallet-thread'&gt;pallet thread&lt;/a&gt;  enables us to do.&lt;/p&gt;&lt;p&gt;Now we want to implement two main requirements, the first generate a blocked amount of running actions, the second make sure not to block the execution of actions (by chunking for example) if threads are available to handle them:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&amp;#40;use '&amp;#91;pallet.thread.executor :only &amp;#40;executor execute&amp;#41;&amp;#93;&amp;#41;  
 
&amp;#40;def pool
  &amp;#40;executor {:prefix &amp;quot;foo&amp;quot; :thread-group-name &amp;quot;foo-grp&amp;quot; :pool-size 4}&amp;#41;&amp;#41;

&amp;#40;defn bound-future &amp;#91;f&amp;#93;
 {:pre &amp;#91;&amp;#40;ifn? f&amp;#41;&amp;#93;}; saves lots of errors
  &amp;#40;execute pool f&amp;#41;&amp;#41;

&amp;#40;defn wait-on &amp;#91;futures&amp;#93;
  &amp;quot;Waiting on a sequence of futures, limited by a constant pool of threads&amp;quot;
  &amp;#40;while &amp;#40;some identity &amp;#40;map &amp;#40;comp not future-done?&amp;#41; futures&amp;#41;&amp;#41;
    &amp;#40;Thread/sleep 1000&amp;#41; 
    &amp;#41;&amp;#41; 

&amp;#40;defn -main &amp;#91;&amp;#93;
  &amp;#40;wait-on &amp;#40;map #&amp;#40;bound-future &amp;#40;fn &amp;#91;&amp;#93;  &amp;#40;action %&amp;#41;&amp;#41;&amp;#41; &amp;#40;range 1000&amp;#41;&amp;#41;&amp;#41;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The print will now look like &lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;0
1
2
3
; a short delay for the next 4 actions to kick into action
1
..
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I found this method to offer a balance between the spread of work and predictable load on the target.&lt;/p&gt;
</description>
<pubDate>
Tue, 24 Jul 2012 00:00:00 +0200
</pubDate>
</item>
<item>
<guid>
http://narkisr.com/posts/20-07-2012-raspberri-pi/
</guid>
<link>
http://narkisr.com/posts/20-07-2012-raspberri-pi/
</link>
<title>
Raspberry foo
</title>
<description>
&lt;p&gt;Iv been lucky to get my hands on a raspberry pie, from the get go it was clear that this device isn't ready for the faint hearted, while there is abundant content around for how to start going the pi is a moving target and things change quickly, this post is a quick start for getting pie going. &lt;/p&gt;&lt;h5 id=&quot;in&amp;#95;this&amp;#95;post&amp;#95;will&amp;#95;cover&quot;&gt;In this post will cover&lt;/h5&gt;&lt;ul&gt;&lt;li&gt;Downloading sdcard image and \&quot;dd'ing\&quot;&lt;/li&gt;&lt;li&gt;Enabling SSH and updating Pi's frimware.&lt;/li&gt;&lt;li&gt;Enabling wifi with the 8192cu chipset:p&lt;/li&gt;&lt;/ul&gt;&lt;h5 id=&quot;downloading&amp;#95;and&amp;#95;dding&quot;&gt;Downloading and dding&lt;/h5&gt;&lt;p&gt;The pi site offers both Arch and Debian  &lt;a href='http://www.raspberrypi.org/downloads'&gt;images&lt;/a&gt; , iv went ahead with Debian mainly since its closer to Ubuntu, note that there are  [beta] (http://rpi-developers.com/frs/download.php/file/20)  &quot; versions out there but iv found the stock one working best.&quot;.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt; $ sudo dd bs=1M if=debian6-19-04-2012.img of=/dev/sdb
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When its done push the sdcard into its slot, make sure to connect the screen before powering up (iv had issue with connecting DVI cable once it was running),&lt;br /&gt; as the boot is done connect it to the internet and run all the updates (note sudo password is raspberry by default, change it afterwards).&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ sudo aptitude update
$ sudo aptitude upgrade
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id=&quot;sshing&quot;&gt;SSHing&lt;/h5&gt;&lt;p&gt;Its time to get our monitor back, we will enable SSH so we can work remotely:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;# boot enable
$ sudo update-rc.d ssh

# ssh won't start without this
$ ssh-keygem -b 1024 -t rsa -f /etc/ssh/ssh&amp;#95;host&amp;#95;key 
$ ssh-keygen -b 1024 -t rsa -f /etc/ssh/ssh&amp;#95;host&amp;#95;rsa&amp;#95;key 
$ ssh-keygen -b 1024 -t rsa -f /etc/ssh/ssh&amp;#95;host&amp;#95;dsa&amp;#95;key 

# enable firewall
$ sudo aptitude install ufw
$ sudo ufw allow 22 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now will update Pi's frimware:&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;# updating frimware
$ sudo wget --no-check-certificate http://goo.gl/1BOfJ -O /usr/bin/rpi-update 
$ sudo chmod +x /usr/bin/rpi-update
$ sudo apt-get install git-core
# avoiding http://tinyurl.com/cbauu4w  
$ sudo ldconfig
$ sudo rpi-update  
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;h5 id=&quot;wifi&quot;&gt;Wifi&lt;/h5&gt;&lt;p&gt;The hardest part in setting up the pi is enabling wireless, this boils down to two main reasons, power consumption and driver compatibility (kernel version wise).  The pi is powered by a 5v power supply (usb phone charger), this means that it has little power to spare for devices connected to its usb ports, high power long range wifi dongle require too much juice. &lt;/p&gt;&lt;p&gt;Among the low bandwidth cost adapters that iv found the  &lt;a href='http://www.amazon.co.uk/Edimax-EW-7811UN-Wireless-802-11b-150Mbps/dp/B003MTTJOY'&gt;EW-7811UN&lt;/a&gt;  draws very little power, in addition it has a very low profile making it barely visible on the pi board, now comes the fun part of making it work.&lt;/p&gt;&lt;p&gt;The info of how setting it up is scattered and inconsistent, the best source out there for setting it up is this forum  &lt;a href='http://www.raspberrypi.org/phpBB3/viewtopic.php?t=6256'&gt;post&lt;/a&gt;   by MrEngman , the post provides a  &lt;a href='http://dl.dropbox.com/u/80256631/install-rtl8188cus.sh'&gt;shell script&lt;/a&gt;  and  &lt;a href='' title=http://dl.dropbox.com/u/80256631/install-rtl8188cus.txt&gt;instructions&lt;/a&gt;  on how to use it,  under compatibility section you can see which driver version matches a kernel version&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ uname -a 
Linux raspberrypi 3.1.9+ #171 PREEMPT Tue Jul 17 01:08:22 BST 2012 armv6l GNU/Linux

# The matching driver version 
rtl8188cus driver versions and compatible Linux versions
-------------------------------------------------------- 

Driver tar file: 8192cu-20120701.tar.gz &amp;#40;http://dl.dropbox.com/u/80256631/8192cu-20120701.tar.gz&amp;#41;
For kernel versions:

Linux raspberrypi 3.1.9+ #171 PREEMPT Tue Jul 17 01:08:22 BST 2012 armv6l GNU/Linux 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Run the installation script:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ sudo ./install-rtl8188cus.sh  
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Lets inspect the results:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;
# the 8192cu driver is in place
$ sudo ls /lib/modules/3.1.9+/kernel/net/wireless
8192cu.ko  cfg80211.ko	lib80211.ko  lib80211&amp;#95;crypt&amp;#95;ccmp.ko  lib80211&amp;#95;crypt&amp;#95;tkip.ko  lib80211&amp;#95;crypt&amp;#95;wep.ko

$ sudo cat /etc/network/interfaces | grep wlan0 -A 5 
allow-hotplug wlan0

auto wlan0

iface wlan0 inet dhcp
wpa-ssid &amp;quot;ssid&amp;quot;
wpa-psk &amp;quot;pass&amp;quot;

$ ifconfig | grep wlan
wlan0     Link encap:Ethernet  HWaddr 00:1f:1f:f2:ff:f8
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Enjoy your pie!&lt;br /&gt;&lt;/p&gt;
</description>
<pubDate>
Fri, 20 Jul 2012 00:00:00 +0200
</pubDate>
</item>
</channel>
</rss>
