summaryrefslogtreecommitdiffstats
path: root/builder/modules.d/dnbd3-rootfs/scripts/tools.sh
blob: bace775e9c32872bdf486c348f837ad3875ab360 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/env bash
# -*- coding: utf-8 -*-
# region imports
# shellcheck source=./rebash/core.sh
source "/usr/lib/rebash/core.sh"
core.import logging
# endregion
tools__doc_test_setup__='
lsblk() {
    if [[ "${@: -1}" == "" ]];then
        echo "lsblk: : not a block device"
        return 1
    fi
    if [[ "${@: -1}" != "/dev/sdb" ]];then
        echo "/dev/sda disk"
        echo "/dev/sda1 part SYSTEM_LABEL 0x7"
        echo "/dev/sda2 part"
    fi
    if [[ "${@: -1}" != "/dev/sda" ]];then
        echo "/dev/sdb disk"
        echo "/dev/sdb1 part boot_partition "
        echo "/dev/sdb2 part system_partition"
    fi
}
blkid() {
    [[ "${@: -1}" != "/dev/sda2" ]] && return 0
    echo "gpt"
    echo "only discoverable by blkid"
    echo "boot_partition"
    echo "192d8b9e"
}
sleep() {
    ((_test_sleep_time++))
}
'

tools_find_block_device() {
    # shellcheck disable=SC2034,SC2016
    local __doc__='
    >>> tools.find_block_device "boot_partition"
    /dev/sdb1
    >>> tools.find_block_device "boot_partition" /dev/sda
    /dev/sda2
    >>> tools.find_block_device "discoverable by blkid"
    /dev/sda2
    >>> tools.find_block_device "_partition"
    /dev/sdb1 /dev/sdb2
    >>> tools.find_block_device "not matching anything"; echo $?
    1
    >>> tools.find_block_device ""; echo $?
    1

    >>> local _test_sleep_time=0
    >>> tools.find_block_device "not matching anything" /dev/sda 10; echo $?
    >>> echo $_test_sleep_time
    1
    10
    '
    local partition_pattern="$1"
    [ "$partition_pattern" = '' ] && return 1
    local device="$2"
    local timeout=0
    [ ! -z "$3" ] && timeout="$3"
    tools_find_block_device_simple() {
        local device_info
        lsblk --noheadings --list --paths --output \
        NAME,TYPE,LABEL,PARTLABEL,UUID,PARTUUID ${device:+"$device"} \
        | sort --unique | while read -r device_info; do
            local current_device
            current_device=$(echo "$device_info" | cut -d' ' -f1)
            if [[ "$device_info" = *"${partition_pattern}"* ]]; then
                echo "$current_device"
            fi
        done
    }
    tools_find_block_device_deep() {
        local device_info
        lsblk --noheadings --list --paths --output NAME ${device:+"$device"} \
        | sort --unique | cut -d' ' -f1 | while read -r current_device; do
            blkid -p -o value "$current_device" \
            | while read -r device_info; do
                if [[ "$device_info" = *"${partition_pattern}"* ]]; then
                    echo "$current_device"
                fi
            done
        done
    }
    while ((timeout >= 0)); do
        local candidates
        candidates=($(tools_find_block_device_simple))
        (( ${#candidates[@]} == 0 )) && candidates=($(tools_find_block_device_deep))
        (( ${#candidates[@]} > 1 )) && echo "${candidates[@]}" && return 1
        (( ${#candidates[@]} == 1 )) && echo "${candidates[0]}" && return 0
        ((timeout == 0)) || sleep 1
        ((timeout--))
    done
    # no candidates
    return 1
}
alias tools.find_block_device="tools_find_block_device"

# region vim modline
# vim: set tabstop=4 shiftwidth=4 expandtab:
# vim: foldmethod=marker foldmarker=region,endregion:
# endregion