[chef] Re: Re: Re: transactional recipe


Chronological Thread 
  • From: Daneel Yaitskov < >
  • To:
  • Subject: [chef] Re: Re: Re: transactional recipe
  • Date: Mon, 25 Nov 2013 21:52:57 +0400

Thank you for nice abstraction for the image dir resource.

I wasn't able to coin it myself. Chef is too new for me. I had to keep a lot in my head at time.
My minimal goal is to express all in chef somehow.

Chef state based model has one big plus such recipes enforce a developer to do very adoptable
scrips. And the faw of this approach makes code bloat.

Look at my final solution based on standard resources. It's a real crap.

  disk = vm_cfg.disk.folder + '/' + vm_cfg.disk.name
  execute "cp #{ vm_cfg.disk.template } #{ disk }" do
    not_if "[ -f #{ disk } ]"
  end

  execute "virsh shutdown #{ name }" do
    only_if "virsh domstate #{ name } | grep -c running"
  end

  ruby_block "resize disk" do
    block do
      resize_raw_image(disk, vm_cfg.disk.size_mb)
    end
    not_if { File.size(disk) == vm_cfg.disk.size_mb  * 1024 * 1024 }
  end

  execute "check loop is free" do
    command "losetup -d /dev/loop0"
    only_if "losetup -a | grep /dev/loop0"
  end

  execute "bind image with device" do
    command "losetup /dev/loop0 #{ disk }"
    not_if "losetup /dev/loop0 | grep #{disk}"
  end

  execute "clear kernel cache" do
    command "partprobe /dev/loop0"
  end

  directory "/tmp/mount-vm-image"

  # if previous fail
  execute "umount image" do
    command "umount /dev/loop0p1"
    only_if "df | grep /tmp/mount-vm-image"
  end

  execute "mount image" do
    command "mount -t ext4 /dev/loop0p1 /tmp/mount-vm-image"
  end

  template "/tmp/mount-vm-image/etc/hostname" do
    source "hostname.erb"
    variables ({  :hostname => vm_fqdn(node.net, name) })
  end

  execute "unmount image" do
    command "umount /dev/loop0p1"
  end

  directory "/tmp/mount-vm-image"  do
    action :delete
  end

  execute " free loop" do
    command "losetup -d /dev/loop0"
  end



On Mon, Nov 25, 2013 at 8:57 PM, Daniel DeLeo < " target="_blank"> > wrote:

On Monday, November 25, 2013 at 8:47 AM, Sean OMeara wrote:

Hi Daneel.

It's possible that Chef (or any other CM tool) may not be the best choice in tooling to do this.

That being said, it *totally is possible*. 

You'll want to create a custom resource type for this, (use the LWRP DSL), and implement the transactional logic in the provider. Always keep in mind that Chef is about ensuring state. "Test for state, take action to repair IF NEEDED"

The state you wish to ensure is "A directory exists inside an unmounted image".  

To pull this off, you'll need to mount the image, check for the directory, repair if needed, then clean up after yourself.
You'll need to do this on *every Chef run*.

Stating the problem like that, I'd personally choose focus on artifact generation using classic procedural scripting out of band of Chef.

If you do choose to implement this with a Chef provider, you'd want to start by thinking about the interface when using the custom resource. Something like this:

# somerecipe.rb
image_directory "example image" do
   path '/srv/images/blackbox.img'
   directory '/var/log/twiddlybits'
   action :create
end

If you want to use the LWRP DSL, the above example will need to be in cookbook named "image", 
If you'd rather use the full blown class interface (a so called HWRP), you can ship it in a cookbook with any name.

Either way, you'll want to implement the transactional logic in the provider, and you'll probably want to use mixlib::shellout to handle stdout.

Don't forget to call new_resource.updated_by_last_action(true) if you have to make the directory.

Good luck!

-s


This is all good advice. If it’s not possible for you to do in a reasonable amount of time, you should look at using not_if or only_if guards on your execute resources so that they’ll always do the right thing instead of chaining notifies together.
 

On Mon, Nov 25, 2013 at 8:03 AM, Daneel Yaitskov < " target="_blank"> > wrote:
All,


I faced with complex relation between resources.
Let's look at this:

remote_file copies a disk image
execute losetup binds the image with a device
execute mount attaches the device to the filesystem
directory creates folder on the mounted image.

This recipe is not reliable because of an exception in a middle of the recipe
requires manual intervention to reset environment.

I.e. I should unmount the device because the first resource would write to mounted .

I could wrap all these resources inside of one ruby_block and use a lot nested begin/ensure
but then I lose any profit of the chef.

I want to preserve linear structure of the recipe and set rollback callbacks on successfully executed resources.

Is there any standard way?

--
Daneel S. Yaitskov

-- 
Daniel DeLeo




--
Daneel S. Yaitskov



Archive powered by MHonArc 2.6.16.

§