I want to automate installing Emacs packages with Cask, Puppet, and Vagrant.



Steps to reproduce

I can do this manually in Emacs on my Mac:

$ emacs
M-: (cask-install)
C-x C-c

This successfully installs my favorite cask packages, allowing me to use them in my .emacs.

I can also do this as an inline bash command:

$ emacs -q --eval "(progn (require 'cask \"~/.cask/cask.el\") (cask-initialize) (setq save-abbrevs nil) (cask-install) (kill-emacs))"

I can also do this inside Vagrant:

$ vagrant ssh
vagrant@precise64$ emacs -q --eval "(progn (require 'cask \"~/.cask/cask.el\") (cask-initialize) (setq save-abbrevs nil) (cask-install) (kill-emacs))"

I can even do this with sudo inside Vagrant, which will become helpful later, so that Puppet doesn' write my Emacs files as root.

vagrant@precise64$ /usr/bin/sudo -u vagrant /usr/bin/emacs -q --eval "(progn (require 'cask \"~/.cask/cask.el\") (cask-initialize) (setq save-abbrevs nil) (cask-install) (kill-emacs))"

However, when I try to execute the command from a Puppet script as exec { ... }, it fails for some reason.

command => "/usr/bin/sudo -u vagrant /usr/bin/emacs -q --eval \"(progn (require 'cask \\\"~/.cask/cask.el\\\") (cask-initialize) (setq save-abbrevs nil) (cask-install) (kill-emacs))\""


debug: Puppet::Type::Package::ProviderApt: Executing '/usr/bin/apt-cache policy emacs24'
debug: Exec[cask](provider=posix): Executing '/usr/bin/sudo -u vagrant /usr/bin/emacs -q --eval "(progn (require 'cask \"~/.cask/cask.el\") (cask-initialize) (setq save-abbrevs nil) (cask-install) (kill-emacs))"'
debug: Executing '/usr/bin/sudo -u vagrant /usr/bin/emacs -q --eval "(progn (require 'cask \"~/.cask/cask.el\") (cask-initialize) (setq save-abbrevs nil) (cask-install) (kill-emacs))"'
err: /Stage[main]//Exec[cask]: Failed to call refresh: /usr/bin/sudo -u vagrant /usr/bin/emacs -q --eval "(progn (require 'cask \"~/.cask/cask.el\") (cask-initialize) (setq save-abbrevs nil) (cask-install) (kill-emacs))" returned 1 instead of one of [0] at /tmp/vagrant-puppet-1/manifests/default.pp:210

I tried temporarily simplifying the command to just:

command => "/usr/bin/sudo -u vagrant /usr/bin/emacs -q --eval \"(kill-emacs)\""

But that fails as well.

Some more context

I'm writing a Vagrant configuration for a crazy development environment, with lots of programming languages and text editors. I plan to add packages for D, Dart, Go, Rust; and to configure nano and maybe R Studio. Since I'm encountering errors, I'm keeping my Vagrant setup small for now: git, Vim, and Emacs.

While working on the Puppet configuration for Vim, I discovered that some commands need special shell environment configurations, like ensuring that HOME is set to /home/vagrant. I tried this with the emacs command, but it's not enough.

I even tried supplying all of the environment variables from the normal vagrant user bash shell to the emacs command, but that didn't work either.

Burning questions

  • What does emacs -q --eval ... require that Puppet/sudo are not offering?
  • Can I supply more options to emacs and/or Puppet to get the failing command to print a more specific error message?


I'm using:

  • Cask 0.5.2
  • Emacs 24 on my Mac and in Vagrant
  • Ubuntu Precise Pangolin 12.04 x64
  • VirtualBox 4.3.6
  • Vagrant 1.4.3
  • Homebrew 0.9.5
  • Mac OS X 10.9.1 Mavericks

But I'm pretty sure the error is due to a misconfiguration on my part in manifests/default.pp Puppet script rather than any bug in the software stack.

Cross-post from Reddit.


Per steckerhalter's suggestion, I was able to run inline Emacs Lisp code from Puppet with --batch, so that an interactive user tty shell is no longer required:

command => "/usr/bin/sudo -u vagrant /usr/bin/emacs -q --batch --eval \"(progn (require 'cask \\\"~/.cask/cask.el\\\") (cask-initialize) (setq save-abbrevs nil) (cask-install) (kill-emacs))\""

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.