summaryrefslogtreecommitdiff
path: root/scripts/image_signing/common.sh
blob: 5f5287aa1eaea35674465dfcde4bb4551e76e3fc (plain)
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/bin/bash
#
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# shellcheck disable=SC2039,SC2059,SC2155

# shellcheck source=./common_minimal.sh
. "$(dirname "$0")/common_minimal.sh"
CROS_LOG_PREFIX="${PROG}: "

# Array of actions that are executed during the clean up process.
declare -a cleanup_actions

# Adds an action to be executed during the clean up process.
# Actions are executed in the reverse order of when they were added.
# ARGS: ACTION
add_cleanup_action() {
  cleanup_actions[${#cleanup_actions[*]}]=$1
}

# Performs the latest clean up action and removes it from the list.
perform_latest_cleanup_action() {
  local num_actions=${#cleanup_actions[*]}
  if [ "${num_actions}" -gt 0 ]; then
    eval "${cleanup_actions[$num_actions-1]} || true" > /dev/null 2>&1
    unset "cleanup_actions[$num_actions-1]"
  fi
}

# Performs clean up by executing actions in the cleanup_actions array in
# reversed order.
cleanup() {
  set +e

  while [ ${#cleanup_actions[*]} -gt 0 ]; do
    perform_latest_cleanup_action
  done

  set -e
}

# ANSI color codes used when displaying messages.
# Taken from src/scripts/common.sh.
V_BOLD_GREEN="\e[1;32m"
V_BOLD_RED="\e[1;31m"
V_BOLD_YELLOW="\e[1;33m"
V_VIDOFF="\e[0m"

# Prints an informational message.
# Taken from src/scripts/common.sh.
# Arg: MESSAGE
info() {
  echo -e >&2 "${V_BOLD_GREEN}${CROS_LOG_PREFIX:-}INFO   : $*${V_VIDOFF}"
}

# Prints a warning message.
# Taken from src/scripts/common.sh.
# Arg: MESSAGE
warn() {
  echo -e >&2 "${V_BOLD_YELLOW}${CROS_LOG_PREFIX:-}WARNING: $*${V_VIDOFF}"
}

# Prints the specified error and exit the script with an error code.
# Taken from src/scripts/common.sh.
# Args: MESSAGE
error() {
  echo -e >&2   "${V_BOLD_RED}${CROS_LOG_PREFIX:-}ERROR  : $*${V_VIDOFF}"
}

TEMP_LOOP_LIST=$(mktemp)

# Setup a loopback device for a file and scan for partitions, with retries.
#
# $1 - The file to back the new loopback device.
# $2-$N - Additional arguments to pass to losetup.
loopback_partscan() {
  local lb_dev image="$1"
  shift

  # We know partition scanning & dev node creation can be racy with udev and
  # the kernel, and the kernel does not sleep/wait for it to finish.  We have
  # to use the partx tool manually as it will sleep until things are finished.
  lb_dev=$(sudo losetup --show -f "$@" "${image}")

  # Cache the path so we can clean it up.
  echo "${lb_dev}" >>"${TEMP_LOOP_LIST}"

  # Ignore problems deleting existing partitions. There shouldn't be any
  # which will upset partx, but that's actually ok.
  sudo partx -d "${lb_dev}" 2>/dev/null || true
  sudo partx -a "${lb_dev}"

  echo "${lb_dev}"
}

# Detach a loopback device set up earlier.
#
# $1 - The loop device to detach.
# $2-$N - Additional arguments to pass to losetup.
loopback_detach() {
  # Retry the deletes before we detach.  crbug.com/469259
  local i
  for (( i = 0; i < 10; i++ )); do
    if sudo partx -d "$1"; then
      break
    fi
    warn "Sleeping & retrying ..."
    sync
    sleep 1
  done
  sudo losetup --detach "$@"
}

# Clear out all loopback devices we setup.
cleanup_loopbacks() {
  local line
  while read -r line; do
    loopback_detach "${line}" 2>/dev/null
  done <"${TEMP_LOOP_LIST}"
  rm -f "${TEMP_LOOP_LIST}"
}

# Usage: lsbval path-to-lsb-file key
# Returns the value for the given lsb-release file variable.
lsbval() {
  local lsbfile="$1"
  local key="$2"
  grep "^${key}=" "${lsbfile}" | sed "s/^${key}=//"
}

# Usage: get_board_from_lsb_release rootfs
# Returns the exact board name from /etc/lsb-release.  This may contain
# dashes or other characters not suitable for variable names.  See the
# next function for that.
get_board_from_lsb_release() {
  local rootfs="$1"
  lsbval "${rootfs}/etc/lsb-release" CHROMEOS_RELEASE_BOARD
}

# Usage: get_boardvar_from_lsb_release rootfs
# Returns the board name from /etc/lsb-release in a mangled form that can
# be used in variable names.  e.g. dashes are turned into underscores.
get_boardvar_from_lsb_release() {
  get_board_from_lsb_release "$@" | sed 's:[-]:_:g'
}

# Usage: restore_lsb_selinux lsb-file
# restore lsb-release security.selinux attribute
restore_lsb_selinux() {
  sudo setfattr -n security.selinux -v "u:object_r:cros_conf_file:s0" "$1"
}

# This will override the trap set in common_minmal.sh
trap "cleanup" INT TERM EXIT

add_cleanup_action "cleanup_temps_and_mounts"
add_cleanup_action "cleanup_loopbacks"