Monday, May 16, 2011

Unbreaking LXC on latest Debian unstable

With recent switch to /run directory in Debian I was getting error from lxc when it was trying to mount /dev/shm in container and failed because /dev/shm is now symlink to inside /run. The simplest fix I found is replacing symlink with bind mount. Here's what I've added to /etc/rc.local

if [ -L /dev/shm ]
then
  mv /dev/shm /dev/shm~
  mkdir /dev/shm
  mount --bind "`readlink -f /dev/shm~`" /dev/shm
fi

Tuesday, May 3, 2011

Setting up Distel and erlang remote shell for membase

I decided to do myself a small present. I've just wrote some Emacs lisp code that via REST API grabs erlang otp node and cookie and connects my emacs with that node. I've made integration with Distel and erlang remote shell. The later was most problematic because of quite weird TTY handling in Erlang shell. But in the end it seems to work great! Grab code here: https://gist.github.com/952958 And the usage is M-x alk-membase-shell and M-x alk-membase-setup-distel.


;; https://github.com/alk/elisp-regex-dsl
(require 'regex-dsl)
;;; http://cvs.savannah.gnu.org/viewvc/*checkout*/emacs/lisp/json.el?root=emacs
(require 'json)
(setq *alk-membase-default-host* "Administrator:asdasd@lh:9000")
(setq *alk-membase-host-split-re* (redsl-to-regexp '(concat (line-begin)
(\? (concat (cap-group (literal ".*?"))
(\? (concat ":" (cap-group (literal ".*?"))))
"@"))
(cap-group (literal ".*?"))
(\? (concat ":" (cap-group (+ (char-set "0-9")))))
(line-end))))
;; (save-match-data
;; (let ((*alk-membase-default-host* "aasd@asd:11"))
;; (string-match *alk-membase-host-split-re* *alk-membase-default-host*)
;; (list (match-string 1 *alk-membase-default-host*)
;; (match-string 2 *alk-membase-default-host*)
;; (match-string 3 *alk-membase-default-host*))))
(defun alk-membase-read-host ()
(let ((value (read-from-minibuffer (concat "host (" *alk-membase-default-host* "): ") nil nil nil nil *alk-membase-default-host*))
(username "Administrator")
(password "adsasd"))
(when (equal value "")
(setq value *alk-membase-default-host*))
value
(save-match-data
(string-match *alk-membase-host-split-re* value)
(let ((username (or (match-string 1 value) username))
(password (or (match-string 2 value) password))
(host (match-string 3 value))
(port (or (match-string 4 value) "8091")))
(list username password host port)))))
;; (alk-membase-read-host)
(defun alk-with-output-in-buffer (fun &rest call-process-args)
(with-temp-buffer
(let ((status (apply #'call-process
(car call-process-args)
""
(list (current-buffer) nil)
nil
(cdr call-process-args))))
(if (eql status 0)
(funcall fun)
(message "%s exited with status %d" (car call-process-args) status)
nil))))
;; (alk-with-output-in-buffer #'(lambda () (buffer-string)) "wget" "-O-" "-q" "--user=Administrator" "--password=asdasd" "http://lh:9000/pools/default")
(defun alk-membase-grab-node-and-cookie (username password host port)
;; (message "grabbing cookie from: %S\n" (list username password host port))
(let* ((json (alk-with-output-in-buffer #'(lambda ()
;; (message "raw output: %S\n" (buffer-string))
(beginning-of-buffer)
(json-read))
"wget" "-O-" "-q"
(concat "--header=Authorization: Basic "
(base64-encode-string (concat username ":" password)))
(concat "http://" host ":" port "/pools/default")))
(nodes (assoc 'nodes json))
(first-node (elt (cdr nodes) 0))
(cookie (cdr (assoc 'otpCookie first-node)))
(otp-node (cdr (assoc 'otpNode first-node))))
(message "cookie and node: %S\n" (list cookie otp-node))
(list otp-node cookie)))
(defun alk-membase-setup-distel (username password host port)
(interactive (alk-membase-read-host))
(let* ((rv (alk-membase-grab-node-and-cookie username password host port))
(otp-node (car rv))
(otp-cookie (cadr rv)))
(message "cookie and node: %S\n" (list otp-cookie otp-node))
(setq derl-cookie otp-cookie)
(setq erl-nodename-cache (intern otp-node))
(setq distel-modeline-node otp-node)
(force-mode-line-update)))
;; (call-interactively 'alk-membase-setup-distel)
(defun alk-membase-shell (username password host port)
(interactive (alk-membase-read-host))
(let* ((rv (alk-membase-grab-node-and-cookie username password host port))
(otp-node (car rv))
(otp-cookie (cadr rv)))
(message "cookie and node: %S\n" (list otp-cookie otp-node))
(unless (and otp-node otp-cookie)
(error "Failed to grap node name and cookie"))
(let ((inferior-erlang-machine-options `("-setcookie" ,otp-cookie
"-name" "membasectl@127.0.0.1" "-hidden"
,@inferior-erlang-machine-options)))
(run-erlang)
(let ((proc (get-buffer-process (current-buffer))))
(comint-send-string proc (format "net_kernel:set_net_ticktime(rpc:call('%s', net_kernel, get_net_ticktime, [])).\n" otp-node))
(sleep-for 0.1)
(comint-send-string proc "")
(sleep-for 0.1)
(comint-send-string proc (concat "r '" otp-node "'\n"))
(sleep-for 0.1)
(comint-send-string proc (concat "c 2\n"))))))
view raw gistfile1.el hosted with ❤ by GitHub