| #!/bin/sh |
| # 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. |
| # |
| # This script downloads and installs the basic packages that the user needs |
| # in developer mode. It also takes care of some configuration details |
| # that arise from not havin write access to the root filesystem. |
| |
| # Constant definitions. |
| P_CONFIG_CROS=/etc/portage |
| P_CONFIG_DEVELOPER=/usr/local/etc/portage |
| EMERGE_PACKAGES="/usr/share/dev-install/bootstrap.packages" |
| |
| # Global variables. |
| BINHOST= |
| |
| # Process flags. |
| . /usr/share/misc/shflags || exit 1 |
| DEFINE_string binhost "" \ |
| "URL of the binhost that emerge will use." b |
| DEFINE_boolean yes "${FLAGS_FALSE}" \ |
| "Do not prompt for input. Assumes yes's to all responses." y |
| DEFINE_boolean only_bootstrap "${FLAGS_FALSE}" \ |
| "Only attempt to install the bootstrap packages." |
| |
| FLAGS "$@" || exit 1 |
| |
| set -e |
| |
| # Get the portage configuration variables. |
| . "${P_CONFIG_CROS}/make.profile/make.defaults" |
| |
| # Echo's args to stderr and prefixes with ERROR(dev_install). |
| error() { |
| echo "ERROR(dev_install): $*" >&2 |
| } |
| |
| # Reads the user's reply and returns 0 if the user responds with y. |
| # Accepts input like echo for the user prompt i.e. $@. |
| yes_or_no() { |
| [ ${FLAGS_yes} -eq ${FLAGS_TRUE} ] && return 0 |
| local reply |
| read -p "$*? (y/N) " reply |
| [ "${reply}" = "y" ] |
| } |
| |
| # Get the static Python binary and portage (emerge script and python modules). |
| download_bootstrap_packages() { |
| # Download packages that python/emerge require into /usr/local/bootsrap. |
| while read line; do |
| local package_url="${BINHOST}/${line}.tbz2" |
| local directory="$(echo "${line}" | cut -d "/" -f 1)" |
| local package_file="${PKGDIR}/${line}.tbz2" |
| mkdir -p -m 0755 "${PKGDIR}/${directory}" |
| echo "Downloading ${package_url}" |
| if ! curl --fail -o "${package_file}" "${package_url}"; then |
| error "Could not download package." |
| error "Command curl --fail -o ${package_file} ${package_url} failed." |
| return 1 |
| fi |
| echo "Extracting ${package_file}" |
| # TODO(sosa): pipeline our download/unpack cycles. |
| # Ignore std error output about trailing garbage after EOF. |
| if ! tar -C /usr/local/ -xjkf "${package_file}" 2>/dev/null; then |
| error "Could not extract package." |
| error "Command tar -C /usr/local -xjf ${package_file} failed." |
| return 1 |
| fi |
| done < "${EMERGE_PACKAGES}" |
| |
| # The python ebuilds set up symlinks in pkg_postinst, but we don't run those |
| # phases (we just run untar above). Plus that logic depends on eselect that |
| # we currently stub out. Hand create the symlinks https://crbug.com/955147. |
| if [ ! -e "/usr/local/usr/bin/python" ]; then |
| ln -sfT "python-wrapper" "/usr/local/usr/bin/python" |
| fi |
| if [ ! -e "/usr/local/usr/bin/python2" ]; then |
| ln -sfT "python2.7" "/usr/local/usr/bin/python2" |
| fi |
| if [ ! -e "/usr/local/usr/bin/python3" ]; then |
| ln -sfT "$(cd /usr/local/usr/bin; echo python3.?)" \ |
| "/usr/local/usr/bin/python3" |
| fi |
| } |
| |
| # Configure emerge in /usr/local. |
| configure_emerge() { |
| # Copy emerge configuration to /usr/local. |
| mkdir -p -m 0755 "${P_CONFIG_DEVELOPER}/make.profile" |
| # Point our local profile to the rootfs one. This allows us to stack. |
| echo "${P_CONFIG_CROS}/make.profile" \ |
| >"${P_CONFIG_DEVELOPER}/make.profile/parent" |
| |
| # Install the package.provided entries for the rootfs. |
| mkdir -p -m 0755 "${P_CONFIG_DEVELOPER}/make.profile/package.provided" |
| local f |
| for f in /usr/share/dev-install/rootfs.provided/*; do |
| ln -sf "${f}" "${P_CONFIG_DEVELOPER}/make.profile/package.provided/" |
| done |
| |
| # Create the directories defined in the portage config files. Permissions are |
| # consistent with the other directories in /usr/local, which is a bind mount |
| # for /mnt/stateful_partition/dev_image. |
| mkdir -p -m 01777 /usr/local/tmp |
| echo "PORTAGE_BINHOST=${BINHOST}" > "${P_CONFIG_DEVELOPER}/make.conf" |
| |
| # Add LD_LIBRARY_PATH within ebuild.sh. |
| # TODO(arkaitzr): find out a cleaner way to do this. |
| sed -i "3 a\export LD_LIBRARY_PATH=\"${LD_LIBRARY_PATH}\"" \ |
| /usr/local/lib/portage/*/ebuild.sh |
| } |
| |
| install_optional_packages() { |
| if yes_or_no "Install virtual/target-os-dev package now"; then |
| emerge virtual/target-os-dev |
| else |
| echo "You can install virtual/target-os-dev later by typing the command:" \ |
| "emerge virtual/target-os-dev" |
| fi |
| } |
| |
| main() { |
| # Sanity check. People often run `su` or `sudo su` and leave off that final |
| # - which means they don't get a proper environment. Catch them here rather |
| # than fail randomly midway through the process. |
| case :${PATH}: in |
| *:/usr/local/bin:*) ;; |
| *) |
| error "Your environment appears to be incomplete. When changing to root," |
| error "did you remember to run the full command (don't forget the dash):" |
| error " $ sudo su -" |
| return 1 |
| ;; |
| esac |
| |
| echo "Starting installation of developer packages." |
| echo "First, we download the necessary files." |
| BINHOST="${FLAGS_binhost}" |
| download_bootstrap_packages |
| if [ ${FLAGS_only_bootstrap} -eq ${FLAGS_TRUE} ]; then |
| echo "dev_install done installing bootstrap packages. Enjoy!" |
| return 0 |
| fi |
| |
| echo "Files downloaded, configuring emerge." |
| configure_emerge |
| |
| echo "Emerge installation complete. Installing additional optional packages." |
| install_optional_packages |
| |
| echo "dev_install done. Enjoy!" |
| } |
| |
| main |