1+ #! /usr/bin/env bash
2+ # -------------------------------------------------------------------------------------------------------------
3+ # Copyright (c) Microsoft Corporation. All rights reserved.
4+ # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
5+ # -------------------------------------------------------------------------------------------------------------
6+
7+ # Syntax: ./common-debian.sh [install zsh flag] [username] [user UID] [user GID] [upgrade packages flag]
8+
9+ INSTALL_ZSH=${1:- " true" }
10+ USERNAME=${2:- " vscode" }
11+ USER_UID=${3:- 1000}
12+ USER_GID=${4:- 1000}
13+ UPGRADE_PACKAGES=${5:- " true" }
14+
15+ set -e
16+
17+ if [ " $( id -u) " -ne 0 ]; then
18+ echo -e ' Script must be run a root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
19+ exit 1
20+ fi
21+
22+ # Treat a user name of "none" as root
23+ if [ " ${USERNAME} " = " none" ] || [ " ${USERNAME} " = " root" ]; then
24+ USERNAME=root
25+ USER_UID=0
26+ USER_GID=0
27+ fi
28+
29+ # Load markers to see which steps have already run
30+ MARKER_FILE=" /usr/local/etc/vscode-dev-containers/common"
31+ if [ -f " ${MARKER_FILE} " ]; then
32+ echo " Marker file found:"
33+ cat " ${MARKER_FILE} "
34+ source " ${MARKER_FILE} "
35+ fi
36+
37+ # Ensure apt is in non-interactive to avoid prompts
38+ export DEBIAN_FRONTEND=noninteractive
39+
40+ # Function to call apt-get if needed
41+ apt-get-update-if-needed ()
42+ {
43+ if [ ! -d " /var/lib/apt/lists" ] || [ " $( ls /var/lib/apt/lists/ | wc -l) " = " 0" ]; then
44+ echo " Running apt-get update..."
45+ apt-get update
46+ else
47+ echo " Skipping apt-get update."
48+ fi
49+ }
50+
51+ # Run install apt-utils to avoid debconf warning then verify presence of other common developer tools and dependencies
52+ if [ " ${PACKAGES_ALREADY_INSTALLED} " != " true" ]; then
53+ apt-get-update-if-needed
54+
55+ PACKAGE_LIST=" apt-utils \
56+ git \
57+ openssh-client \
58+ less \
59+ iproute2 \
60+ procps \
61+ curl \
62+ wget \
63+ unzip \
64+ nano \
65+ jq \
66+ lsb-release \
67+ ca-certificates \
68+ apt-transport-https \
69+ dialog \
70+ gnupg2 \
71+ libc6 \
72+ libgcc1 \
73+ libgssapi-krb5-2 \
74+ libicu[0-9][0-9] \
75+ liblttng-ust0 \
76+ libstdc++6 \
77+ zlib1g \
78+ locales \
79+ sudo"
80+
81+ # Install libssl1.1 if available
82+ if [[ ! -z $( apt-cache --names-only search ^libssl1.1$) ]]; then
83+ PACKAGE_LIST=" ${PACKAGE_LIST} libssl1.1"
84+ fi
85+
86+ # Install appropriate version of libssl1.0.x if available
87+ LIBSSL=$( dpkg-query -f ' ${db:Status-Abbrev}\t${binary:Package}\n' -W ' libssl1\.0\.?' 2>&1 || echo ' ' )
88+ if [ " $( echo " $LIBSSL " | grep -o ' libssl1\.0\.[0-9]:' | uniq | sort | wc -l) " -eq 0 ]; then
89+ if [[ ! -z $( apt-cache --names-only search ^libssl1.0.2$) ]]; then
90+ # Debian 9
91+ PACKAGE_LIST=" ${PACKAGE_LIST} libssl1.0.2"
92+ elif [[ ! -z $( apt-cache --names-only search ^libssl1.0.0$) ]]; then
93+ # Ubuntu 18.04, 16.04, earlier
94+ PACKAGE_LIST=" ${PACKAGE_LIST} libssl1.0.0"
95+ fi
96+ fi
97+
98+ echo " Packages to verify are installed: ${PACKAGE_LIST} "
99+ apt-get -y install --no-install-recommends ${PACKAGE_LIST} 2> >( grep -v ' debconf: delaying package configuration, since apt-utils is not installed' >&2 )
100+
101+ PACKAGES_ALREADY_INSTALLED=" true"
102+ fi
103+
104+ # Get to latest versions of all packages
105+ if [ " ${UPGRADE_PACKAGES} " = " true" ]; then
106+ apt-get-update-if-needed
107+ apt-get -y upgrade --no-install-recommends
108+ apt-get autoremove -y
109+ fi
110+
111+ # Ensure at least the en_US.UTF-8 UTF-8 locale is available.
112+ # Common need for both applications and things like the agnoster ZSH theme.
113+ if [ " ${LOCALE_ALREADY_SET} " != " true" ]; then
114+ echo " en_US.UTF-8 UTF-8" >> /etc/locale.gen
115+ locale-gen
116+ LOCALE_ALREADY_SET=" true"
117+ fi
118+
119+ # Create or update a non-root user to match UID/GID - see https://aka.ms/vscode-remote/containers/non-root-user.
120+ if id -u $USERNAME > /dev/null 2>&1 ; then
121+ # User exists, update if needed
122+ if [ " $USER_GID " != " $( id -G $USERNAME ) " ]; then
123+ groupmod --gid $USER_GID $USERNAME
124+ usermod --gid $USER_GID $USERNAME
125+ fi
126+ if [ " $USER_UID " != " $( id -u $USERNAME ) " ]; then
127+ usermod --uid $USER_UID $USERNAME
128+ fi
129+ else
130+ # Create user
131+ groupadd --gid $USER_GID $USERNAME
132+ useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME
133+ fi
134+
135+ # Add add sudo support for non-root user
136+ if [ " ${EXISTING_NON_ROOT_USER} " != " ${USERNAME} " ]; then
137+ echo $USERNAME ALL=\( root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME
138+ chmod 0440 /etc/sudoers.d/$USERNAME
139+ EXISTING_NON_ROOT_USER=" ${USERNAME} "
140+ fi
141+
142+ # Ensure ~/.local/bin is in the PATH for root and non-root users for bash. (zsh is later)
143+ if [ " ${DOT_LOCAL_ALREADY_ADDED} " != " true" ]; then
144+ echo " export PATH=\$ PATH:\$ HOME/.local/bin" | tee -a /root/.bashrc >> /home/$USERNAME /.bashrc
145+ chown $USER_UID :$USER_GID /home/$USERNAME /.bashrc
146+ DOT_LOCAL_ALREADY_ADDED=" true"
147+ fi
148+
149+ # Optionally install and configure zsh
150+ if [ " ${INSTALL_ZSH} " = " true" ] && [ ! -d " /root/.oh-my-zsh" ] && [ " ${ZSH_ALREADY_INSTALLED} " != " true" ]; then
151+ apt-get-update-if-needed
152+ apt-get install -y zsh
153+ curl -fsSLo- https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh | bash 2>&1
154+ echo " export PATH=\$ PATH:\$ HOME/.local/bin" >> /root/.zshrc
155+ if [ " ${USERNAME} " != " root" ]; then
156+ cp -fR /root/.oh-my-zsh /home/$USERNAME
157+ cp -f /root/.zshrc /home/$USERNAME
158+ sed -i -e " s/\/root\/.oh-my-zsh/\/home\/$USERNAME \/.oh-my-zsh/g" /home/$USERNAME /.zshrc
159+ chown -R $USER_UID :$USER_GID /home/$USERNAME /.oh-my-zsh /home/$USERNAME /.zshrc
160+ fi
161+ ZSH_ALREADY_INSTALLED=" true"
162+ fi
163+
164+ # Write marker file
165+ mkdir -p " $( dirname " ${MARKER_FILE} " ) "
166+ echo -e " \
167+ PACKAGES_ALREADY_INSTALLED=${PACKAGES_ALREADY_INSTALLED} \n\
168+ LOCALE_ALREADY_SET=${LOCALE_ALREADY_SET} \n\
169+ EXISTING_NON_ROOT_USER=${EXISTING_NON_ROOT_USER} \n\
170+ DOT_LOCAL_ALREADY_ADDED=${DOT_LOCAL_ALREADY_ADDED} \n\
171+ ZSH_ALREADY_INSTALLED=${ZSH_ALREADY_INSTALLED} " > " ${MARKER_FILE} "
0 commit comments