# Cookbook:: irrigate-docker
# Recipe:: install
#
# Copyright:: The Orchard

prerequisite_packages = %w(
  ca-certificates
  curl
  gpg
)

prerequisite_packages.each do |name|
  package name
end

if node['docker']['custom_data_block_device']
  device = node['docker']['custom_data_block_device']
  mount_point = node['docker']['custom_data_mount_point']
  fs_label = node['docker']['custom_data_filesystem_label']

  # Check if block device exists
  device_exists = ::File.exist?(device)

  # Check if block device is mounted
  mounted = false
  if shell_out("mountpoint -q #{mount_point}").exitstatus == 0
    mounted = true
    Chef::Log.info("Block device #{device} is already mounted")
  end

  if !device_exists
    Chef::Log.warn("Block device #{device} does not exist, skipping format")
  elsif mounted
    Chef::Log.info("Block device #{device} is already mounted, skipping format")
  else
    ruby_block 'detect existing filesystem' do
      block do
        require 'mixlib/shellout'
        cmd = Mixlib::ShellOut.new("blkid -o value -s TYPE #{device}")
        cmd.run_command

        if cmd.error?
          Chef::Log.warn("Failed to detect filesystem on #{device}: #{cmd.stderr}")
          node.run_state['fs_type'] = nil
        else
          node.run_state['fs_type'] = cmd.stdout.strip.empty? ? nil : cmd.stdout.strip
        end
      end
    end

    execute 'format ext4 on custom data device' do
      command "mkfs -t ext4 -L #{fs_label} #{device}"
      not_if { node.run_state['fs_type'] == 'ext4' }
      not_if { mounted }
      only_if { device_exists }
    end

    # Ensure a filesystem label exists if requested
    ruby_block 'detect existing filesystem label' do
      block do
        require 'mixlib/shellout'
        cmd = Mixlib::ShellOut.new("blkid -o value -s LABEL #{device}")
        cmd.run_command
        if cmd.error?
          Chef::Log.warn("Failed to detect filesystem label on #{device}: #{cmd.stderr}")
          node.run_state['fs_label'] = nil
        else
          node.run_state['fs_label'] = cmd.stdout.strip.empty? ? nil : cmd.stdout.strip
        end
      end
      only_if { fs_label }
    end

    directory mount_point do
      owner 'root'
      group 'root'
      mode '0755'
      action :create
    end

    mount mount_point do
      device fs_label
      device_type :label
      fstype 'ext4'
      options 'defaults,noatime,nodiratime,discard'
      action [:enable, :mount]
    end
  end
end

remote_file '/etc/apt/keyrings/docker.asc' do
  owner 'root'
  group 'root'
  mode '0644'
  source 'https://download.docker.com/linux/debian/gpg'
  action :create_if_missing
  sensitive true
end

apt_repository 'docker' do
  components ['stable']
  signed_by '/etc/apt/keyrings/docker.asc'
  trusted false
  uri 'https://download.docker.com/linux/debian'
end

docker_packages = %w(
  docker-ce
  docker-ce-cli
  containerd.io
  docker-buildx-plugin
  docker-compose-plugin
)

docker_packages.each do |name|
  package name
end

template '/etc/docker/daemon.json' do
  source 'etc_docker_daemon.json.erb'
  owner 'root'
  group 'root'
  mode '0644'
  variables(
    config: node['docker']['daemon']
  )
  notifies :restart, 'service[docker]', :delayed
end

template '/etc/containerd/config.toml' do
  source 'containerd_config.toml.erb'
  owner 'root'
  group 'root'
  mode '0644'
  notifies :restart, 'service[containerd]', :delayed
end

# Start service.
service 'docker' do
  supports status: true, reload: true
  action [:enable, :start]
end

service 'containerd' do
  supports status: true, reload: true
  action [:enable, :start]
end

group 'docker' do
  append true
  members node['docker']['users']
end
