aboutsummaryrefslogtreecommitdiff
path: root/tools/create_base_image_hostlib.sh
blob: dafefbd8f708b05e1cea687ca22002291a3833e0 (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
#!/bin/bash

# Common code to build a host image on GCE

# INTERNAL_extra_source may be set to a directory containing the source for
# extra package to build.

# INTERNAL_IP can be set to --internal-ip run on a GCE instance
# The instance will need --scope compute-rw

source "${ANDROID_BUILD_TOP}/external/shflags/shflags"

DEFINE_string build_instance \
  "${USER}-build" "Instance name to create for the build" "i"
DEFINE_string build_project "$(gcloud config get-value project)" \
  "Project to use for scratch"
DEFINE_string build_zone "$(gcloud config get-value compute/zone)" \
  "Zone to use for scratch resources"
DEFINE_string dest_image "vsoc-host-scratch-${USER}" "Image to create" "o"
DEFINE_string dest_family "" "Image family to add the image to" "f"
DEFINE_string dest_project "$(gcloud config get-value project)" \
  "Project to use for the new image" "p"
DEFINE_string launch_instance "" \
  "Name of the instance to launch with the new image" "l"
DEFINE_string source_image_family "debian-10" \
  "Image familty to use as the base" "s"
DEFINE_string source_image_project debian-cloud \
  "Project holding the base image" "m"
DEFINE_string repository_url \
  "https://github.com/google/android-cuttlefish.git" \
  "URL to the repository with host changes" "u"
DEFINE_string repository_branch main \
  "Branch to check out" "b"


SSH_FLAGS=(${INTERNAL_IP})

fatal_echo() {
  echo "$1"
  exit 1
}

wait_for_instance() {
  alive=""
  while [[ -z "${alive}" ]]; do
    sleep 5
    alive="$(gcloud compute ssh "${SSH_FLAGS[@]}" "$@" -- uptime || true)"
  done
}

package_source() {
  local url="$1"
  local branch="$2"
  local repository_dir="${url/*\//}"
  local debian_dir="$(basename "${repository_dir}" .git)"
  if [[ $# -eq 4 ]]; then
    debian_dir="${repository_dir}/$4"
  fi
  git clone "${url}" -b "${branch}"
  dpkg-source -b "${debian_dir}"
  rm -rf "${debian_dir}"
}

main() {
  set -o errexit
  set -x
  PZ=(--project=${FLAGS_build_project} --zone=${FLAGS_build_zone})
  if [[ -n "${FLAGS_dest_family}" ]]; then
    dest_family_flag=("--family=${FLAGS_dest_family}")
  else
    dest_family_flag=()
  fi
  scratch_dir="$(mktemp -d)"
  pushd "${scratch_dir}"
  package_source "${FLAGS_repository_url}" "${FLAGS_repository_branch}" \
    "cuttlefish-common_${FLAGS_version}"
  popd
  source_files=(
    "${ANDROID_BUILD_TOP}/device/google/cuttlefish/tools/create_base_image_gce.sh"
    ${scratch_dir}/*
  )
  if [[ -n "${INTERNAL_extra_source}" ]]; then
    source_files+=("${INTERNAL_extra_source}"/*)
  fi

  delete_instances=("${FLAGS_build_instance}" "${FLAGS_dest_image}")
  if [[ -n "${FLAGS_launch_instance}" ]]; then
    delete_instances+=("${FLAGS_launch_instance}")
  fi
  gcloud compute instances delete -q \
    "${PZ[@]}" "${delete_instances[@]}" || \
      echo Not running
  gcloud compute disks delete -q \
    "${PZ[@]}" "${FLAGS_dest_image}" || echo No scratch disk
  gcloud compute images delete -q \
    --project="${FLAGS_build_project}" "${FLAGS_dest_image}" || echo Not respinning
  gcloud compute disks create \
    "${PZ[@]}" \
    --image-family="${FLAGS_source_image_family}" \
    --image-project="${FLAGS_source_image_project}" \
    "${FLAGS_dest_image}"
  local gpu_type="nvidia-tesla-p100-vws"
  gcloud compute accelerator-types describe "${gpu_type}" "${PZ[@]}" || \
    fatal_echo "Please use a zone with ${gpu_type} GPUs available."
  gcloud compute instances create \
    "${PZ[@]}" \
    --machine-type=n1-standard-16 \
    --image-family="${FLAGS_source_image_family}" \
    --image-project="${FLAGS_source_image_project}" \
    --boot-disk-size=200GiB \
    --accelerator="type=${gpu_type},count=1" \
    --maintenance-policy=TERMINATE \
    "${FLAGS_build_instance}"
  wait_for_instance "${PZ[@]}" "${FLAGS_build_instance}"
  # Ubuntu tends to mount the wrong disk as root, so help it by waiting until
  # it has booted before giving it access to the clean image disk
  gcloud compute instances attach-disk \
      "${PZ[@]}" \
      "${FLAGS_build_instance}" --disk="${FLAGS_dest_image}"
  # beta for the --internal-ip flag that may be passed via SSH_FLAGS
  gcloud beta compute scp "${SSH_FLAGS[@]}" "${PZ[@]}" \
    "${source_files[@]}" \
    "${FLAGS_build_instance}:"
  gcloud compute ssh "${SSH_FLAGS[@]}" \
    "${PZ[@]}" "${FLAGS_build_instance}" -- \
    ./create_base_image_gce.sh
  gcloud compute instances delete -q \
    "${PZ[@]}" "${FLAGS_build_instance}"
  gcloud compute images create \
    --project="${FLAGS_build_project}" \
    --source-disk="${FLAGS_dest_image}" \
    --source-disk-zone="${FLAGS_build_zone}" \
    --licenses=https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx \
    "${dest_family_flag[@]}" \
    "${FLAGS_dest_image}"
  gcloud compute disks delete -q "${PZ[@]}" \
    "${FLAGS_dest_image}"
  if [[ -n "${FLAGS_launch_instance}" ]]; then
    gcloud compute instances create "${PZ[@]}" \
      --image-project="${FLAGS_build_project}" \
      --image="${FLAGS_dest_image}" \
      --machine-type=n1-standard-4 \
      --scopes storage-ro \
      --accelerator="type=${gpu_type},count=1" \
      --maintenance-policy=TERMINATE \
      "${FLAGS_launch_instance}"
  fi
  cat <<EOF
    echo Test and if this looks good, consider releasing it via:

    gcloud compute images create \
      --project="${FLAGS_dest_project}" \
      --source-image="${FLAGS_dest_image}" \
      --source-image-project="${FLAGS_build_project}" \
      "${dest_family_flag[@]}" \
      "${FLAGS_dest_image}"
EOF
}