Error when installing package with 'apt' module, not so when installing directly

2,212 views
Skip to first unread message

haarts

unread,
Nov 24, 2012, 1:42:15 PM11/24/12
to ansible...@googlegroups.com
Dear list,

I've run into a puzzling issue. I'm creating a playbook to install Crashplan on my Raspberry Pi. On of the steps involves installing the Java lib "libjna-java". This does not work:

PLAY [pi] ********************* 

GATHERING FACTS ********************* 
<pi> REMOTE_MODULE setup 
ok: [pi]

TASK: [install java packages] ********************* 
<pi> REMOTE_MODULE apt pkg=libjna-java state=installed
failed: [pi] => {"failed": true}
msg: 'apt-get install 'libjna-java' ' failed: E: Sub-process /usr/bin/dpkg returned an error code (2)


FATAL: all hosts have already failed -- aborting

PLAY RECAP ********************* 
pi                             : ok=1    changed=0    unreachable=0    failed=1 

Going to the machine via SSH and issueing: 'apt-get install libjna-java' works without a hitch. I'm a bit at a loss here. How do I debug this? 

During the playbook execution I ran 'ps ax' to see what commands where issued, nothing strange as far as I can tell. For completeness sake:
/bin/sh -c DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical /usr/bin/apt-get --option Dpkg::Options::=--force-confold -q -y  install 'libjna-java' 

I hope someone knows what's up.

With kind regards,

Michael DeHaan

unread,
Nov 24, 2012, 2:24:06 PM11/24/12
to ansible...@googlegroups.com
Something in the package script wanted a real TTY?

-- Michael
--
 
 

haarts

unread,
Nov 24, 2012, 2:27:54 PM11/24/12
to ansible...@googlegroups.com
When running apt-get local it just installed. Quite literally 'no questions asked'. It's just a lib. That is how you'd know there was a TTY right? When some user input is required?

Michael DeHaan

unread,
Nov 24, 2012, 3:26:08 PM11/24/12
to ansible...@googlegroups.com
no idea, java famously required X for years.  Maybe someone else can take a look at the package source.

-- Michael
--
 
 

Lorin Hochstein

unread,
Nov 24, 2012, 5:15:15 PM11/24/12
to ansible...@googlegroups.com
I tried installing the libjna-java package using ansible on an ubuntu virtual machine, and I didn't have any issues. This is what I did:

$ ansible vm -s -m apt -a "pkg=libjna-java"
vm | success >> {
    "changed": true
}

Then, checked inside the machine to see if it was installed:

vagrant@precise64:~$ dpkg -l | grep libjna-java
ii  libjna-java                     3.2.7-4                    Dynamic access of native libraries from Java without JNI



Take care,

Lorin
--
Lorin Hochstein
Lead Architect - Cloud Services
Nimbis Services, Inc.





On Nov 24, 2012, at 2:27 PM, haarts <harm...@gmail.com> wrote:

--
 
 

Dag Wieers

unread,
Nov 24, 2012, 6:42:00 PM11/24/12
to ansible...@googlegroups.com
On Sat, 24 Nov 2012, haarts wrote:

> I've run into a puzzling issue. I'm creating a playbook to install
> Crashplan on my Raspberry Pi. On of the steps involves installing the Java
> lib "libjna-java". This does not work:
>
> PLAY [pi] *********************
>
> GATHERING FACTS *********************
> <pi> REMOTE_MODULE setup
> ok: [pi]
>
> TASK: [install java packages] *********************
> <pi> REMOTE_MODULE apt pkg=libjna-java state=installed
> failed: [pi] => {"failed": true}
> msg: 'apt-get install 'libjna-java' ' failed: E: Sub-process /usr/bin/dpkg
> returned an error code (2)

Looking at the output, I wonder why there is an additional quoting in that
msg. I would have expected:

msg: 'apt-get install libjna-java '
failed: E: Sub-process /usr/bin/dpkg

Somehow it feels as if you added quotes that shouldn't be there. In YAML,
strings don't have to be quoted !

--
-- dag wieers, d...@wieers.com, http://dag.wieers.com/
-- dagit linux solutions, in...@dagit.net, http://dagit.net/

[Any errors in spelling, tact or fact are transmission errors]

haarts

unread,
Nov 24, 2012, 8:05:28 PM11/24/12
to ansible...@googlegroups.com
Thanks for all the responses! I've made some headway but the mystery deepens.

I'm starting to suspect that it has something to do with the fact that the Pi is an ARM machine, seeing that Lorin is able to install without issues. 
The quoting isn't it. I double checked my YAML file.

The playbook defines 2 packages to be installed, one 'libjna-java', the other 'openjdk-6-jre' (see it in a Gist: https://gist.github.com/4141972). I've added line 8: "-name: install JNA". Now the playbook fails on the 'openjdk-6-jre' package! With the same error (aside from the package name). 

This is getting weird.

Harm

haarts

unread,
Nov 24, 2012, 8:27:50 PM11/24/12
to ansible...@googlegroups.com
I found the issue; installing as root works, with sudo it doesn't. I've tested with a random other package, in this case 'curl'.

With sudo:
TASK: [install curl] ********************* 
<pi> ESTABLISH CONNECTION FOR USER: pi on PORT 22 TO pi
<pi> EXEC /bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-1353806171.19-173008960117788 && chmod a+rx $HOME/.ansible/tmp/ansible-1353806171.19-173008960117788 && echo $HOME/.ansible/tmp/ansible-1353806171.19-173008960117788'
<pi> REMOTE_MODULE apt pkg=curl state=installed
<pi> PUT /var/folders/rd/8nngsjnd0ds0y690_x0j18k80000gn/T/tmpaYtqFr TO /home/pi/.ansible/tmp/ansible-1353806171.19-173008960117788/apt
<pi> EXEC /bin/sh -c 'sudo -k && sudo -p "[sudo via ansible, key=prcrexrotbynmicxjtowyyhldqrigudq] password: " -u root /bin/sh -c '"'"'/usr/bin/python -tt /home/pi/.ansible/tmp/ansible-1353806171.19-173008960117788/apt; rm -rf /home/pi/.ansible/tmp/ansible-1353806171.19-173008960117788/ >/dev/null 2>&1'"'"''
failed: [pi] => {"failed": true}
msg: 'apt-get install 'curl' ' failed: E: Sub-process /usr/bin/dpkg returned an error code (2)


FATAL: all hosts have already failed -- aborting


With root:
TASK: [install curl] ********************* 
<pi> ESTABLISH CONNECTION FOR USER: root on PORT 22 TO pi
<pi> EXEC /bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-1353806498.34-90561343419662 && echo $HOME/.ansible/tmp/ansible-1353806498.34-90561343419662'
<pi> REMOTE_MODULE apt pkg=curl state=installed
<pi> PUT /var/folders/rd/8nngsjnd0ds0y690_x0j18k80000gn/T/tmpF1zDoj TO /root/.ansible/tmp/ansible-1353806498.34-90561343419662/apt
<pi> EXEC /bin/sh -c '/usr/bin/python -tt /root/.ansible/tmp/ansible-1353806498.34-90561343419662/apt; rm -rf /root/.ansible/tmp/ansible-1353806498.34-90561343419662/ >/dev/null 2>&1'
changed: [pi] => {"changed": true}

I'm not sure what the problem is.... Some unbalanced quotes perhaps?

Harm

Karl Ostendorf

unread,
May 14, 2013, 4:50:53 AM5/14/13
to ansible...@googlegroups.com
I was having the exact problem on Wheezy Debian 7 x64 - using a normal user to install packages with sudo. I was however able to reproduce the problem by logging in via ssh to the machine and executing apt-get on the command line. In my case, I was trying to install rsync:

apt-get -y install rsync

The problem was that dpkg was not in the normal user's path as were all the normal root paths: /usr/local/sbin:/usr/sbin:/sbin.  So to solve the problem you need to explicitly set the path for the apt module as follows

- name: install debian packages
  apt: pkg=rsync state=latest
  environment:
    PATH: /usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin

Hope this helps!

Serge van Ginderachter

unread,
May 14, 2013, 5:22:14 AM5/14/13
to ansible...@googlegroups.com
This is indeed a case that happens on Debian, as Ubuntu tends to put sbin paths also in a regular user's folder.
You might consider extending the path for your sudo user also.

The best solution would be to let the apt module look for the apt-get|aptitude binaries and execute them with full absolute path, whereas it now just calls the binary by name without path.



--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Michael DeHaan

unread,
May 14, 2013, 8:13:35 AM5/14/13
to ansible...@googlegroups.com
Yes, this should definitely use the find module code in lib/ansible/module_common.

We should not be relying on user paths.

Please file a ticket and (if you are feeling generous) look around some of the other modules for how they do it and apply a fix :)

--Michael
--
Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Brian Coca

unread,
May 14, 2013, 9:13:28 AM5/14/13
to ansible...@googlegroups.com

This path is normally set correctly in the sudoers file (by default).

Brian Coca

Serge van Ginderachter

unread,
May 14, 2013, 2:04:25 PM5/14/13
to ansible...@googlegroups.com

On 14 May 2013 15:13, Brian Coca <bria...@gmail.com> wrote:
This path is normally set correctly in the sudoers file (by default).

​Seems so, yes. According to sudoers(5)​:

     By default, the env_reset option is enabled.  This causes commands to be executed with a new, minimal environment.  On AIX (and Linux systems without PAM), the environment is initialized with
     the contents of the /etc/environment file.  The new environment contains the TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_* variables in addition to variables from the
     invoking process permitted by the env_check and env_keep options.  This is effectively a whitelist for environment variables.

​on my system (ubuntu) /etc/environments contains:

serge@cyberlab:~$ cat /etc/environment 
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"

However, on a Debian 6, I see that environment file is empty.

So validating executables with the common_module methods would still be a good idea.


Serge

Brian Coca

unread,
May 14, 2013, 2:56:03 PM5/14/13
to ansible...@googlegroups.com
I would almost qualify this as a 'bug' in Debian 6



--
Brian Coca
Stultorum infinitus est numerus
0110000101110010011001010110111000100111011101000010000001111001011011110111010100100000011100110110110101100001011100100111010000100001
Pedo mellon a minno

Brian Coca

unread,
May 14, 2013, 2:56:48 PM5/14/13
to ansible...@googlegroups.com
or you should have it set in sudoers file itself:

Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

Michael DeHaan

unread,
May 14, 2013, 3:00:51 PM5/14/13
to ansible...@googlegroups.com
Repeating myself.. :)

We need to use the find module code and not rely on the users path.



On Tue, May 14, 2013 at 2:56 PM, Brian Coca <bria...@gmail.com> wrote:
or you should have it set in sudoers file itself:

Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"



On Tue, May 14, 2013 at 2:56 PM, Brian Coca <bria...@gmail.com> wrote:
I would almost qualify this as a 'bug' in Debian 6



--
Brian Coca
Stultorum infinitus est numerus
0110000101110010011001010110111000100111011101000010000001111001011011110111010100100000011100110110110101100001011100100111010000100001
Pedo mellon a minno



--
Brian Coca
Stultorum infinitus est numerus
0110000101110010011001010110111000100111011101000010000001111001011011110111010100100000011100110110110101100001011100100111010000100001
Pedo mellon a minno

--

Brian Coca

unread,
May 14, 2013, 3:30:28 PM5/14/13
to ansible...@googlegroups.com
agreed, but this should still work 'as is' in most cases. Will patch apt tonight, should be quick one.

Brian Coca

unread,
May 14, 2013, 3:40:03 PM5/14/13
to ansible...@googlegroups.com
refraining from rewriting the whole thing to avoid 'global', but this is what patch should look like:

diff --git a/library/packaging/apt b/library/packaging/apt
index 41380e6..1a0ea84 100644
--- a/library/packaging/apt
+++ b/library/packaging/apt
@@ -117,8 +117,6 @@ import os
 import datetime
 
 # APT related constants
-APTITUDE_CMD = "aptitude"
-APT_GET_CMD = "apt-get"
 APT_ENVVARS = "DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical"
 DPKG_OPTIONS = '-o "Dpkg::Options::=--force-confdef" -o "Dpkg::Options::=--force-confold"'
 APT_GET_ZERO = "0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded."
@@ -265,6 +263,9 @@ def main():
     except:
         module.fail_json(msg="Could not import python modules: apt, apt_pkg. Please install python-apt package.")
 
+    global APTITUDE_CMD = module.get_bin_path("aptitude")
+    global APT_GET_CMD = module.get_bin_path("apt-get")
+
     p = module.params
     install_recommends = p['install_recommends']


Serge van Ginderachter

unread,
May 14, 2013, 3:49:45 PM5/14/13
to ansible...@googlegroups.com
Testing this on my Debian 6 box, i was actually not able to reproduce this (OK, the OP did mention Debian 7...):

serge@cyberlab:~/src/ansible$ ansible debian6 -u serge -K -m apt -a "pkg=sshpass state=latest" -vvv
sudo password: 
debian6 | success >> {
    "changed": true
}
serge@cyberlab:~/src/ansible$ ansible debian6 -u serge -K -m shell -a "echo $PATH" -vvv
sudo password: 
debian6 | success | rc=0 >>
/home/serge/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
serge@cyberlab:~/src/ansible$ ansible debian6 -u serge -K -m shell -a "which apt-get; which dpkg" -vvv
sudo password: 
debian6 | success | rc=0 >>
/usr/bin/apt-get
/usr/bin/dpkg


I'm also puzzled by the OP mentioning this error:

msg: 'apt-get install 'curl' ' failed: E: Sub-process /usr/bin/dpkg returned an error code (2)

which seems to tell us apt-get is ran fine, and the path to dpkg is no problem either.

Are we looking at some other bug than this $PATH thing?


Serge

Serge van Ginderachter

unread,
May 14, 2013, 3:53:43 PM5/14/13
to ansible...@googlegroups.com
​Brian,​

On 14 May 2013 21:40, Brian Coca <bria...@gmail.com> wrote:
+    global APTITUDE_CMD = module.get_bin_path("aptitude")
+    global APT_GET_CMD = module.get_bin_path("apt-get")

Ii see one problem with this:

Whilst apt-get can be expected to be installed on any debian based system, ​aptitude cannot. A very bare system won't have it (which was the reason for one of my previous patches on this module), so this should remain optional, and only checked if explicitly chosen a option needing aptitude.


(PS: unrelated, we might also consider letting users choose between apt-get and aptitude for other tasks besides upgradingn wchis is now the only case where aptitude gets used)


Serge


Brian Coca

unread,
May 14, 2013, 3:59:27 PM5/14/13
to ansible...@googlegroups.com
ah, my patch doesn't fix the issue. The path seems to be needed for programs executed in pre/upg/post scripts from the packages or possibly dpkg-configure.

Not that the module should not use get_bin_path, alas, that is not the source of the errors, but I'll still submit the patch.

I'm torn between considering it a packager bug (use full paths or builtins!) or distro bug (sudo should have sbin paths defined, they've always had).

Brian Coca

unread,
May 15, 2013, 10:38:37 PM5/15/13
to ansible...@googlegroups.com
I'll fix my patch so the absence of aptitude doesn't create issues
Reply all
Reply to author
Forward
0 new messages