# # Cookbook:: esh_undocker # Resource:: extract # # Copyright:: 2022, https://easyself.host # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. unified_mode true property :image, String, name_property: true #property :tag, String, required: true #property :network, String, required: true #property :env, Array, required: true default_action :extract action :extract do image = new_resource.image parts = image.split(':') tag = parts.pop url, image = parts.join(':').split('/', 2) #tag = new_resource.tag #network = new_resource.network #env = new_resource.env path = '/opt/undocker' directory path do owner 'root' group 'root' mode '0755' action :create end apt_package %w(umoci jq) current_digest = `jq -r '.from_descriptor_path.descriptor_walk[].digest' < #{path}/#{image}/umoci.json`.strip latest_digest = `skopeo inspect oci:#{Chef::Config['file_cache_path']}/#{image}-#{tag}:#{tag} | jq -r .Digest`.strip directory "#{path}/#{image}" do recursive true action :delete only_if { current_digest != latest_digest } end execute "undockerize #{image} (convert to OCI runtime bundle)" do command <<~EOT umoci unpack \ --image #{Chef::Config['file_cache_path']}/#{image}-#{tag}:#{tag} \ #{path}/#{image} done EOT # Weird, umoci return 2 not 0... returns 2 not_if { current_digest == latest_digest } end directory "#{path}/#{image}" do owner 'root' group 'root' mode '0755' action :create end # bash "patch #{path}/#{image}/config.json rootfs path" do # code <<~EOT # cat <<< $(jq '.root.path = "#{path}/#{image}/rootfs"' #{path}/#{image}/config.json) > #{path}/#{image}/config.json # EOT # action :run # not_if do # `jq '.root.path == "#{path}/#{image}/rootfs"' #{path}/#{image}/config.json`.strip == 'true' # end # end # # bash "patch #{path}/#{image}/config.json network namespace" do # code <<~EOT # cat <<< $(jq 'del(.linux.namespaces[] | select(.type == "network"))' #{path}/#{image}/config.json) > #{path}/#{image}/config.json # EOT # action :run # only_if do # `jq -r '.linux.namespaces[] | select(.type == "network") | .type' #{path}/#{image}/config.json`.strip == 'network' # end # only_if { network == 'host' } # end # # file "/usr/local/bin/patch_process_env_#{image}.sh" do # content <<~EOT # #!/usr/bin/bash # set -euo pipefail # cat <<< $(jq '.process.env += #{env}' #{path}/#{image}/config.json) > #{path}/#{image}/config.json # EOT # owner 'root' # group 'root' # mode '0755' # action :create # notifies :run, "execute[patch #{path}/#{image}/config.json process env]", :immediately # end # # execute "patch #{path}/#{image}/config.json process env" do # command "/usr/local/bin/patch_process_env_#{image}.sh" # action :nothing # # TODO: Add a guard, complicated to find if env vars are missing # end end