Handle zypper exit code

The exit code from zypper tells us useful bits. For instance, we can
know that the zypper command needs to be run again (after the zypp stack
got updated, for instance), or that a reboot is required (which we do
for now).

Also do all this in a ruby_block to have more control on what's
happening.
Save one_shot_run attribute early in the recipe

This is safer, especially if there's a reboot.