#!/bin/bash

set -eo pipefail

die()
{
  echo "$@" >&2
  exit 1
}

cwd=$(pwd)
backing_filename="backingfile"
target_name="iqn.2024-10.com.test.storage:target01"
localhost="127.0.0.1"
portal="${localhost}:3260"
initiator_name="iqn.2024-10.com.test.storage:initiator01"

# Install necessary iSCSI modules which are in -extra in Ubuntu
if dpkg-vendor --derives-from Ubuntu; then
    apt-get install -y "linux-modules-extra-$(uname -r)" \
        || die "Could not install iSCSI linux modules"
fi

# Load iSCSI/TCP data-path module
modprobe iscsi_tcp \
    || die "Failed modprobe of iscsi_tcp kernel module"
lsmod | grep scsi


# create backing file
targetcli backstores/fileio create name="${backing_filename}" size=1M file_or_dev="${cwd}/${backing_filename}" \
    || die "Failed to create backing file"
# create Target Portal Group (TPG)
targetcli iscsi/ create "${target_name}" \
    || die "Failed to create target"

# cleanup any existing portal
targetcli iscsi/${target_name}/tpg1/portals delete ip_address=0.0.0.0 ip_port=3260 \
    || echo "-"
# create new portal
targetcli iscsi/${target_name}/tpg1/portals create \
    || die "Failed to create portal"

# set backing file to target
targetcli "iscsi/${target_name}/tpg1/luns" create "/backstores/fileio/${backing_filename}" \
    || die "Failed to set backing file"

# set acls
targetcli iscsi/${target_name}/tpg1/ set attribute generate_node_acls=1 \
    || die "Failed to set acls node generation"
targetcli iscsi/${target_name}/tpg1/acls create "${initiator_name}" \
    || die "Failed to set acls"
echo "InitiatorName=${initiator_name}" > "/etc/iscsi/initiatorname.iscsi"

targetcli "ls"

systemctl restart iscsid \
    || die "Failed to restart iscsid"
systemctl restart open-iscsi \
    || die "Failed to restart open-iscsi"

# scan for targets (locally)
iscsiadm --mode discovery --type sendtargets --portal "${localhost}" \
    || die "Failed to scan for local targets"

# login and establish disk node (/dev/sdX)
iscsiadm --mode node --targetname "${target_name}" --portal "${portal}" --login \
    || die "Failed to login in and establish disk node"
udevadm settle --timeout 60 \
    || die "Failed during udevadm settle"

# Determine the disk device name
disk=$(lsscsi -g | grep ${backing_filename} | head -n1 | awk '{ print $6 }')

echo
echo "Status after initial setup"
sginfo "${disk}" | grep "^Product:" \
    || die "Failed to query for product name from sginfo"

ls -l "${disk}" \
    || die "Failed to find ${disk}"

echo
echo "Check SCSI Logical Unit Number (LUN) report"
sg_luns "${disk}" | grep "Lun list length = " \
    || die "Failed to get lun for ${disk}"

echo
echo "Lookup op codes, checking for op code 88 'Read'"
sg_opcodes "${disk}" | grep "^ 88" | grep "Read" \
    || die "Failed check of opcodes on ${disk}"

echo
echo "Reset the disk"
sg_reset "${disk}" \
    || die "Failed to reset disk"

echo
echo "Scan the disk to check that it is active"
sg_scan -av "${disk}" \
    || die "Failed to scan disk for activity"

echo
echo "Check the SCSI VERIFY command is handled and succeeds"
sg_verify "${disk}" \
    || die "Failed to check verify command"

echo
echo "Read the mode pages with the SCSI MODE SENSE command"
sg_modes "${disk}" \
    || die "Failed to read mode pages"

echo
echo "Check data write behavior"
sg_dd bs=512 if=/dev/random of="${disk}" count=1000 2>/dev/null \
    || "Failed writing to ${disk}"

echo
echo "Check data read behavior"
sg_dd bs=512 if=/etc/lsb-release of="${disk}" 2>/dev/null \
    || "Failed writing lsb-release info to ${disk}"
sg_dd count=1 if="${disk}" of=/dev/stdout 2>/dev/null | grep '^DISTRIB_ID' 2>/dev/null \
    || "Failed reading from ${disk}"
