New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Local chroot support v2 #2106

Merged
merged 3 commits into from Feb 23, 2013

Conversation

Projects
None yet
3 participants
@mmoya
Contributor

mmoya commented Feb 17, 2013

Add support for acting on a local chroot. This could be used for building a preconfigured virtual OS image starting from a raw distro bootstrap.

Requires running ansible as root.

Includes two fixes for fails when /proc is not mounted.

Using

Example of use with a Debian boostrap:

$ sudo deboostrap squeeze /tmp/squeeze-chroot
$ sudo chroot /tmp/squeeze-chroot apt-get update
$ sudo chroot /tmp/squeeze-chroot apt-get -V --no-install-recommends install python python-apt
$ sudo -E ansible-playbook -vvv -c chroot -i '/tmp/squeeze-chroot,' all -m setup
$ sudo -E ansible-playbook -vvv -c chroot -i '/tmp/squeeze-chroot,' test-playbook.yml

an example test-playbook.yml could be:


---
- hosts: all
  tasks:
    - name: echo something to temp
      shell: "echo Yaaayy!" >/tmp/foobar.txt

    - name: installs a package
      apt: pkg=less state=latest

Notes

Same as #2082 but now chroot is an independent connection type as suggested.

@dhozac

This comment has been minimized.

Contributor

dhozac commented Feb 17, 2013

How does this work when -f 1 is used? I see nothing to un-chroot in there.

@mmoya

This comment has been minimized.

Contributor

mmoya commented Feb 17, 2013

@dhozac I can't see what you mean with 'nothing to un-chroot thing'. I tested this as well with -i './chroot-test-dir1,./chroot-test-dir2' -f 1 and it worked as expected.

@mpdehaan

This comment has been minimized.

Contributor

mpdehaan commented Feb 17, 2013

Thanks, will take a look shortly

@dhozac

This comment has been minimized.

Contributor

dhozac commented Feb 19, 2013

Yeah, it is simpler than I was expecting.

I don't think lib should be a requirement, not all chroots will have that (consider e.g. /lib64).

Checking euid should probably be in the connection plugin instead of in bin/ansible or bin/ansible-playbook, as you can specify connection: chroot in the play and such. However, euid might not be enough as you can grant select capabilities (such as chroot) rather easily on recent Linux...

executable in the subprocess.Popen call will always None, as you explicitly ensure that is the case. You can even leave it off in this case.

Paths should be resolved with abspath inside of the chroot to follow symlinks correctly, otherwise you may start writing things outside of the chroot, and fail to make the files available as intended.

@mmoya

This comment has been minimized.

Contributor

mmoya commented Feb 19, 2013

Working on the issues. Thanks.

mmoya added some commits Feb 13, 2013

Prevent traceback when /etc/mtab is not available
* get_file_contents returns None when file is not available.
  When /etc/mtab is pointing to /proc/mounts and /proc is not
  mounted, mtab.split will traceback.
Add support for running modules chrooted in a local dir
Adds 'chroot' connection for executing modules chrooted to
a local dir. Requires running ansible as root.

chroot dirs should be specified in the inventory like any
other host.

You can do things like:

$ sudo -E ansible -vvv -f 1 "./chroot1,./chroot2" -c chroot \
  all -m setup
$ sudo -E ansible-playbook -vvv -f 1 -i "./chroot1,./chroot2" \
  -c chroot some-playbook.yml

some-playbook.yml:
---
- hosts: all
  tasks:
    - name: echo something
      shell: echo "Yaaay!" >/tmp/foobar.txt
    - name: install less
      apt: pkg=less state=latest
@mmoya

This comment has been minimized.

Contributor

mmoya commented Feb 20, 2013

  • /lib requirement removed.
  • executable not being passed to subprocess.Popen anymore.
  • sudo stuff removed, it was an unreachable code path anyways because of sudoable = False.
  • Ensure remote paths are always inside the chroot.
  • euid check moved to connection.
    There are a compromise here as there isn't (AFAICT) a way to ask for current process capabilities with plain python 2.6. I see users of this feature more likely to use sudo instead of someway granting CAP_SYS_CHROOT to the ansible process. In that case I find nicer checking for EUID == 0 and fail properly. On the other hand those having CAP_SYS_CHROOT and unable/unwilling to sudo will be unhappy.

@mpdehaan mpdehaan merged commit 9a493ef into ansible:devel Feb 23, 2013

@mpdehaan

This comment has been minimized.

Contributor

mpdehaan commented Feb 23, 2013

This looks very good and I've merged this.

I think the next logical addition would be a module that could create a chroot if it did not already exist, useful?

@mmoya

This comment has been minimized.

Contributor

mmoya commented Feb 23, 2013

Not sure how to handle idempotence in such a module, maybe testing that /bin/sh is able to run.

Now that you mention, I've started to pondering something like:

inventory:

[chroots]
/path/to/chroot1 suite=squeeze
/path/to/chroot2 suite=sid

playbook:

---
- hosts: chroots
  create_chroot: True
  tasks:
     ...

or create_chroot_if_missing or ensure_chroot_exists. What do you think?

@mpdehaan

This comment has been minimized.

Contributor

mpdehaan commented Feb 23, 2013

Directory exists and contains /bin/sh seems good.

I was thinking of it as a module that would run on the localhost, not one that would actually use the chroot type.

OTOH, creating a chroot is very distro specific.

@mpdehaan

This comment has been minimized.

Contributor

mpdehaan commented Feb 23, 2013

debootstrap makes things pretty easy, just saw your tweet.

Wonder if there is something similarly nice for CentOS/RHEL/Fedora

On Sat, Feb 23, 2013 at 6:48 PM, Maykel Moya notifications@github.comwrote:

Not sure how to handle idempotence in such a module, maybe testing that
/bin/sh is able to run.

Now that you mention, I've started to pondering something like:

inventory:

[chroots]
/path/to/chroot1 suite=squeeze
/path/to/chroot2 suite=sid

playbook:


  • hosts: chroots
    create_chroot: True
    tasks:
    ...

or create_chroot_if_missing or ensure_chroot_exists. What do you think?


Reply to this email directly or view it on GitHubhttps://github.com//pull/2106#issuecomment-14000530.

@mmoya

This comment has been minimized.

Contributor

mmoya commented Feb 24, 2013

So...

- name: install squeeze debootstrap
  debootstrap: suite=squeeze target=/path/to/squeeze-chroot mirror=http://ftp.ca.debian.org/debian state=present

I'll add it to queue.

febootstrap seems to be the same for Fedora.

@mmoya mmoya deleted the mmoya:local-chroot-support-v2 branch Feb 24, 2013

@mpdehaan

This comment has been minimized.

Contributor

mpdehaan commented Feb 24, 2013

perhaps it should be called 'chroot' then and take something like a
family=debian/fedora ?

On Sat, Feb 23, 2013 at 7:33 PM, Maykel Moya notifications@github.comwrote:

So...

I'll add it to queue.

febootstrap http://linux.die.net/man/8/febootstrap seems to be the same
for Fedora.


Reply to this email directly or view it on GitHubhttps://github.com//pull/2106#issuecomment-14001084.

@renard renard referenced this pull request Jan 3, 2014

Closed

Chroot execution #5491

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment