Domain Driven Architecture

6. November 2014 By: Michael Jerger

Configmanagement with Pallet - First Steps

As a new and rising star pallet is a new player in the config management universe. The following post describes how to do the first steps in pallet. These are

  • setting up your own pallet IDE,
  • initializing your first pallet project,
  • preparing a freshly set up vm and finally
  • connecting to this vm.

From my experience I know that the versions of the software that is used are important for pallet. So my versions are:

  • Ubuntu14.04
  • pallet 0.8.0-RC.9
  • Leiningen 2.4.3

Setting up your own IDE

For pallet-beginners the first challenge is to set up an IDE for pallet. If you are also a clojure greenhorn (as I am) then we need a clojure IDE too. I will describe the stack based on Spring Eclipse. The steps for setting up the IDE are:

  1. Install Java / Git
    1. apt-get install openjdk-7-jdk
    2. apt-get install git
  2. Install Leiningen - the clojure build tool
    1. mkdir -p /opt/leiningen
    2. cd /opt/leiningen
    3. wget https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein
    4. chown a+x lein
    5. cp -s /opt/leiningen/lein /usr/local/bin/
  3. Install Spring Eclipse
    1. mkdir -p /opt/eclipse
    2. cd /opt/eclipse
    3. wget http://download.springsource.com/release/STS/3.6.2/dist/e4.4/spring-tool-suite-3.6.2.RELEASE-e4.4.1-linux-gtk-x86_64.tar.gz
    4. tar -xzf spring-tool-suite-3.6.2.RELEASE-e4.4.1-linux-gtk-x86_64.tar.gz
  4. Start eclipse & install clojure plugin (counterclockwise)
    1. /opt/eclipse/STS
    2. Select Help -> Install new Software
    3. Add a new location http://updatesite.ccw-ide.org/stable to "work with"
    4. Select "Counterclockwise" & press Finish

Setup the Pallet Project

The steps to set up a pallet-project are following the official palletops.com tutorial http://palletops.com/pallet/doc/first-steps/ - just a few additional explanations are added.

  1. Create pallet project
    1. cd [your code location]
    2. lein new pallet my-learning-pallet
  2. Open the new project in eclipse
    1. start eclipse (for me it's /opt/eclipse/sts-3.6.2.RELEASE/STS)
  3. Create project from filesystem
    1. create new clojure project
    2. chose no default location
    3. select your my-learning-pallet folder
    4. wait (... eclipse will pull all declared dependencies)

So let's have a look at the newly created pallet project.

  1. project.clj defines dependencies for your project (more doc you'll find at https://github.com/technomancy/leiningen)
  2. pallet.clj (typically not shown in eclipse Package Explorer) is describing the pallet project. The created project.clj file is reflecting the usage with cloud providers. As we are going to connect to existing nodes, we will declare providers and similar stuff direct in the code. We are not going to use pallet.clj.
  3. The credentials mentioned in the tutorial we will also declare directly in code.

You will find the complete and run approved code for this example at https://github.com/DomainDrivenArchitecture/learning-pallet. If you find not running parts, leave me a short issue message as a your support request.

Describe the Bootstrap for existing nodes

The full POC (Proof of concept) requirements can be found at https://requirements.domaindrivenarchitecture.org/CmRequirementsPocPallet. But for the first step, we will just connect to an existing node. Pallet uses ssh for connecting to other servers. So for preparation, a ssh connection to our target node should be possible. You can test this with

  1. ssh [an user]@[an ip] - ssh root@192.168.35.12 for example.
  2. In order to have some fun, let's start an interactive clojure console called REPL in eclipse
    1. Select your project
    2. Right click and choose Leiningen -> launch headless REPL
  3. Lets create the clojure hull (the code can be found at https://github.com/DomainDrivenArchitecture/learning-pallet/blob/master/src/org/domaindrivenarchitecture/configmanagement/first_connect.clj)
    (ns org.domaindrivenarchitecture.configmanagement.first-connect
       (:require
         [pallet.compute :as compute]
         [pallet.api :as api])
       (:gen-class :main true))
    
  4. Lets load this code in REPL (find full shortkey collection at http://doc.ccw-ide.org/keyboard-shortcuts.html#interactionwiththerepl)
    1. Move your cursor in to the editor
    2. Load with [CTRL] + [ALT] + [S]
  5. Let's switch to our declared namespace
    1. Move your cursor in to the editor
    2. Change namespace with [CTRL] + [ALT] + [N]
  6. As a first step, let's declare the our user credentials. I've created a special pallet user on my target node. This user has to be added to sudoers group.
    1. (def pallet-user (api/make-user "pallet" :password "test123"))
    2. Reload File in REPL with [CTRL] + [ALT] + [S]
  7. We specify now, which config we want to apply. Just for testing the pure connection, an empty configuration would be enough.
    1. Define:
        (def poc-spec
          (api/server-spec
            :phases {
            :connect (pallet.api/plan-fn ) }
          ))
      
    2. Reload ...
  8. Now let's define the place, we will apply this spec to
    1. The group:
        (def poc-group
         (api/group-spec "poc" :extends [poc-spec] ))
      
    2. And the target node:
        (def my-pocket-cloud
         (compute/instantiate-provider "node-list"
          :node-list "palletPoc"
          "poc"
          "192.168.35.12"
          :ubuntu))
      
    3. Reload ... :-)
  9. Now let's bring all parts together and create a main method which we can call
    1. Define:
        (defn -main [& args]
         (apply api/lift
          poc-group
          :user pallet-user
          :compute my-pocket-cloud args))
      
    2. Reload ...
  10. For a first test we start the main method with
    1. Enter in REPL:
        (-main :phase :connect)
      
    2. And press [RETURN]

Inspect your Success

Pallet will now produce much output in your console. Let's inspect it to find out, whether we where successful:

  1. The last line should look like
    18:32:57.669 [operate-38] DEBUG pallet.algo.fsm.event-machine - :dofsm-lift - in state :step-completed fire :complete
    
    (Check :complete)
  2. Did pallet connect with pallet user?
    18:32:53.405 [operate-40] DEBUG pallet.ssh.execute - authentication {:sudo-user nil, :state-group nil,
     :private-key nil, :public-key nil, :sudo-password "*****", :private-key-path nil, :no-sudo nil,
     :public-key-path nil, :passphrase nil, :username "pallet", :state-root nil, :password "*****"}
     18:32:56.723 [operate-40] DEBUG pallet.transport.ssh - Create ssh transport state: {:server "192.168.35.12", :port 22
     18:32:56.852 [operate-40] DEBUG pallet.ssh.execute - 192.168.35.12 ==> -----------------------------------------
     18:32:56.855 [operate-40] DEBUG pallet.ssh.execute - 192.168.35.12 ==> #!/usr/bin/env bash
     18:32:56.860 [operate-40] DEBUG pallet.ssh.execute - 192.168.35.12 ==> set -h
     18:32:56.861 [operate-40] DEBUG pallet.ssh.execute - 192.168.35.12 ==> echo {
     18:32:56.861 [operate-40] DEBUG pallet.ssh.execute - 192.168.35.12 ==> echo :os '"'$(uname -s)'"'
     18:32:56.861 [operate-40] DEBUG pallet.ssh.execute - 192.168.35.12 ==> echo :rev '"'$(uname -r)'"'
     18:32:56.862 [operate-40] DEBUG pallet.ssh.execute - 192.168.35.12 ==> echo :mach '"'$(uname -m)'"'
     18:32:56.862 [operate-40] DEBUG pallet.ssh.execute - 192.168.35.12 ==> echo }
     18:32:56.862 [operate-40] DEBUG pallet.ssh.execute - 192.168.35.12 ==>
     18:32:56.862 [operate-40] DEBUG pallet.ssh.execute - 192.168.35.12 ==> exit $?
    
    (Check :username "pallet")
  3. Do we get live information back from the node?
    18:32:56.899 [operate-40] DEBUG pallet.ssh.execute - ssh-script-on-target command {:env-cmd "/usr/bin/env",
     :env nil, :env-fwd [:SSH_AUTH_SOCK], :prefix ["echo" "'test123'" "|" "/usr/bin/sudo" "-S"],
     :execv ("/bin/bash" "/tmp/palletT1upZ")}
     18:32:57.031 [operate-40] DEBUG pallet.execute - 192.168.35.12 <== {
     18:32:57.035 [operate-40] DEBUG pallet.execute - 192.168.35.12 <== :os "Linux"
     18:32:57.038 [operate-40] DEBUG pallet.execute - 192.168.35.12 <== :rev "3.13.0-24-generic"
     18:32:57.039 [operate-40] DEBUG pallet.execute - 192.168.35.12 <== :mach "x86_64"
     18:32:57.039 [operate-40] DEBUG pallet.execute - 192.168.35.12 <== }
    

Finally, does all this look good? Then congratulations, you've gotten your first successful contact with pallet.


Tags: clojure tutorial howto pallet config management infrastructure

Powered by Cryogen | Free Website Template by Download Website Templates | Datenschutzerklärung | Impressum