How to enhance an existing provider?


#1

I’m still on the up-slope of my Chef learning curve…

What I’d like to do is enhance the Chef::Provider::File. It seems to me that the documentation section “Extending an existing provider” would apply here, but I don’t fully understand how it would work. I would create a mixin and put it into the library directory – and then what? How would all my cookbooks – and the community ones I’m using - know to use this mixin?

Specifically, what I’m trying to accomplish is fix one of the major annoyances in Chef; it not only doesn’t support SELinux, but actively clobbers the SELinux context for all he files, templates etc. that it creates. So my recipes are littered with execute resources for the “restorecon” utility to reset this everwhere I use a file-related resource (templates, remote_file, cookbook file etc.). It is becoming unmanageable, especially with community cookbooks that of course don’t have my hack added.

Conceptually the fix is simple: in the file provider, in addition to setting the file permissions, I would also need to call restorecon.

Rather than hacking the File resource itself, I would like to put this feature into my SELinux cookbook, and have that somehow add a Mixin to the File resource.

I just can’t figure out how to do that.

Thanks!


#2

Hi!

Excellent question. The best way to do this is to use a cookbook to
monkey patch the Chef::Provider::File class, so you can experiment
with it without having to modify core Chef.

As it turns out, I started making a pass at this very issue a few
years ago, but never got around to finishing it.

Here’s a good place to start!

Let me know if you have any questions or need any assistance.

-s

On Tue, Jan 1, 2013 at 5:26 PM, subscription@kkeane.com wrote:

I’m still on the up-slope of my Chef learning curve…

What I’d like to do is enhance the Chef::Provider::File. It seems to me that
the documentation section “Extending an existing provider” would apply here,
but I don’t fully understand how it would work. I would create a mixin and
put it into the library directory – and then what? How would all my
cookbooks – and the community ones I’m using - know to use this mixin?

Specifically, what I’m trying to accomplish is fix one of the major
annoyances in Chef; it not only doesn’t support SELinux, but actively
clobbers the SELinux context for all he files, templates etc. that it
creates. So my recipes are littered with execute resources for the
“restorecon” utility to reset this everwhere I use a file-related resource
(templates, remote_file, cookbook file etc.). It is becoming unmanageable,
especially with community cookbooks that of course don’t have my hack added.

Conceptually the fix is simple: in the file provider, in addition to setting
the file permissions, I would also need to call restorecon.

Rather than hacking the File resource itself, I would like to put this
feature into my SELinux cookbook, and have that somehow add a Mixin to the
File resource.

I just can’t figure out how to do that.

Thanks!


#3

Look in libraries/monkey.rb

That particular code assumes that when you write a file, you want to
give it the same selinux context as it’s containing directory by
default. Opinions on that?

It needs some heavy work and uses a raw string as the context
representation instead of breaking it into its individual parts.

It’s a start.

On Tue, Jan 1, 2013 at 5:46 PM, Sean OMeara someara@gmail.com wrote:

Hi!

Excellent question. The best way to do this is to use a cookbook to
monkey patch the Chef::Provider::File class, so you can experiment
with it without having to modify core Chef.

As it turns out, I started making a pass at this very issue a few
years ago, but never got around to finishing it.

Here’s a good place to start!

https://github.com/someara/cookbook-selinux/tree/monkeys

Let me know if you have any questions or need any assistance.

-s

On Tue, Jan 1, 2013 at 5:26 PM, subscription@kkeane.com wrote:

I’m still on the up-slope of my Chef learning curve…

What I’d like to do is enhance the Chef::Provider::File. It seems to me that
the documentation section “Extending an existing provider” would apply here,
but I don’t fully understand how it would work. I would create a mixin and
put it into the library directory – and then what? How would all my
cookbooks – and the community ones I’m using - know to use this mixin?

Specifically, what I’m trying to accomplish is fix one of the major
annoyances in Chef; it not only doesn’t support SELinux, but actively
clobbers the SELinux context for all he files, templates etc. that it
creates. So my recipes are littered with execute resources for the
“restorecon” utility to reset this everwhere I use a file-related resource
(templates, remote_file, cookbook file etc.). It is becoming unmanageable,
especially with community cookbooks that of course don’t have my hack added.

Conceptually the fix is simple: in the file provider, in addition to setting
the file permissions, I would also need to call restorecon.

Rather than hacking the File resource itself, I would like to put this
feature into my SELinux cookbook, and have that somehow add a Mixin to the
File resource.

I just can’t figure out how to do that.

Thanks!


#4

Thank you so much! I’ll check out the monkey patch; sounds just like what I need!

As for the assumption: I think there may be a better, and easier, way to go about that. SELinux already contains a database of all the contexts that files should have; you access it with the semanage fcontext command. The restorecon utility that I was planning to use simply looks in this database and applies whatever context RedHat/CentOS/… are supposed to have in the first place.

This is better because the assumption “use the containing directory’s context” isn’t always true. For instance, in the /usr/lib64/nagios/plugins directory, some plugins need to have unconfined context, while others will run fine confined.

By the way, an alternate approach would be to change how chef puts files in its destination. I think this would go too deep into Chef for me to do, though, but would be the best solution.

Currently, as far as I can tell, Chef creates a file in a temporary directory (which gives it the usr_tmp_t context) and then moves it into place (keeping the context). That’s probably how the context gets clobbered in the first place. Instead, chef should first create the file in the temporary location, but instead of moving it, create a new one (which will have the correct SELinux context) and copy the content of the temporary file over.

In any case, thanks for your monkey patch! That’s going to help me dramatically.

-----Original Message-----
From: Sean OMeara [mailto:someara@gmail.com]
Sent: Tuesday, January 01, 2013 2:52 PM
To: chef@lists.opscode.com
Subject: [chef] Re: How to enhance an existing provider?

Look in libraries/monkey.rb

That particular code assumes that when you write a file, you want to give it the same selinux context as it’s containing directory by default. Opinions on that?

It needs some heavy work and uses a raw string as the context representation instead of breaking it into its individual parts.

It’s a start.

On Tue, Jan 1, 2013 at 5:46 PM, Sean OMeara someara@gmail.com wrote:

Hi!

Excellent question. The best way to do this is to use a cookbook to
monkey patch the Chef::Provider::File class, so you can experiment
with it without having to modify core Chef.

As it turns out, I started making a pass at this very issue a few
years ago, but never got around to finishing it.

Here’s a good place to start!

https://github.com/someara/cookbook-selinux/tree/monkeys

Let me know if you have any questions or need any assistance.

-s

On Tue, Jan 1, 2013 at 5:26 PM, subscription@kkeane.com wrote:

I’m still on the up-slope of my Chef learning curve…

What I’d like to do is enhance the Chef::Provider::File. It seems to
me that the documentation section “Extending an existing provider”
would apply here, but I don’t fully understand how it would work. I
would create a mixin and put it into the library directory – and then
what? How would all my cookbooks – and the community ones I’m using - know to use this mixin?

Specifically, what I’m trying to accomplish is fix one of the major
annoyances in Chef; it not only doesn’t support SELinux, but actively
clobbers the SELinux context for all he files, templates etc. that it
creates. So my recipes are littered with execute resources for the
“restorecon” utility to reset this everwhere I use a file-related
resource (templates, remote_file, cookbook file etc.). It is becoming
unmanageable, especially with community cookbooks that of course don’t have my hack added.

Conceptually the fix is simple: in the file provider, in addition to
setting the file permissions, I would also need to call restorecon.

Rather than hacking the File resource itself, I would like to put
this feature into my SELinux cookbook, and have that somehow add a
Mixin to the File resource.

I just can’t figure out how to do that.

Thanks!


#5

Glad to hear it. Feel free to send in a pull request or 5 and we’ll
get it tested and moved into the official selinux coobook.

On Tue, Jan 1, 2013 at 7:12 PM, Kevin Keane (subscriptions)
subscription@kkeane.com wrote:

Thank you so much! I’ll check out the monkey patch; sounds just like what I need!

As for the assumption: I think there may be a better, and easier, way to go about that. SELinux already contains a database of all the contexts that files should have; you access it with the semanage fcontext command. The restorecon utility that I was planning to use simply looks in this database and applies whatever context RedHat/CentOS/… are supposed to have in the first place.

This is better because the assumption “use the containing directory’s context” isn’t always true. For instance, in the /usr/lib64/nagios/plugins directory, some plugins need to have unconfined context, while others will run fine confined.

By the way, an alternate approach would be to change how chef puts files in its destination. I think this would go too deep into Chef for me to do, though, but would be the best solution.

Currently, as far as I can tell, Chef creates a file in a temporary directory (which gives it the usr_tmp_t context) and then moves it into place (keeping the context). That’s probably how the context gets clobbered in the first place. Instead, chef should first create the file in the temporary location, but instead of moving it, create a new one (which will have the correct SELinux context) and copy the content of the temporary file over.

In any case, thanks for your monkey patch! That’s going to help me dramatically.

-----Original Message-----
From: Sean OMeara [mailto:someara@gmail.com]
Sent: Tuesday, January 01, 2013 2:52 PM
To: chef@lists.opscode.com
Subject: [chef] Re: How to enhance an existing provider?

Look in libraries/monkey.rb

That particular code assumes that when you write a file, you want to give it the same selinux context as it’s containing directory by default. Opinions on that?

It needs some heavy work and uses a raw string as the context representation instead of breaking it into its individual parts.

It’s a start.

On Tue, Jan 1, 2013 at 5:46 PM, Sean OMeara someara@gmail.com wrote:

Hi!

Excellent question. The best way to do this is to use a cookbook to
monkey patch the Chef::Provider::File class, so you can experiment
with it without having to modify core Chef.

As it turns out, I started making a pass at this very issue a few
years ago, but never got around to finishing it.

Here’s a good place to start!

https://github.com/someara/cookbook-selinux/tree/monkeys

Let me know if you have any questions or need any assistance.

-s

On Tue, Jan 1, 2013 at 5:26 PM, subscription@kkeane.com wrote:

I’m still on the up-slope of my Chef learning curve…

What I’d like to do is enhance the Chef::Provider::File. It seems to
me that the documentation section “Extending an existing provider”
would apply here, but I don’t fully understand how it would work. I
would create a mixin and put it into the library directory – and then
what? How would all my cookbooks – and the community ones I’m using - know to use this mixin?

Specifically, what I’m trying to accomplish is fix one of the major
annoyances in Chef; it not only doesn’t support SELinux, but actively
clobbers the SELinux context for all he files, templates etc. that it
creates. So my recipes are littered with execute resources for the
“restorecon” utility to reset this everwhere I use a file-related
resource (templates, remote_file, cookbook file etc.). It is becoming
unmanageable, especially with community cookbooks that of course don’t have my hack added.

Conceptually the fix is simple: in the file provider, in addition to
setting the file permissions, I would also need to call restorecon.

Rather than hacking the File resource itself, I would like to put
this feature into my SELinux cookbook, and have that somehow add a
Mixin to the File resource.

I just can’t figure out how to do that.

Thanks!