Further script improvments
This commit is contained in:
Родитель
c840fb0bc2
Коммит
202fae4ba5
|
@ -1,20 +1,27 @@
|
||||||
# Development Container Scripts
|
# Development Container Scripts
|
||||||
|
|
||||||
This folder contains a set of scripts that can be referenced by Dockerfiles in development container "definitions" that are found under the [`containers` directory](../containers). When referenced properly, a hash is generated upon release that ensures that only the expected version of this script is executed. See [this Dockerfile](../container-templates/dockerfile/.devcontainer/Dockerfile) for an example.
|
This folder contains a set of scripts that can be referenced by Dockerfiles in development container "definitions" that are found under the [`containers` directory](../containers). You are also free to use them in your own dev container configurations.
|
||||||
|
|
||||||
The `test` sub-folder includes Debian, Alpine, and RedHat based dev containers that can be used to test the scripts.
|
The `test` sub-folder includes Debian, Alpine, and RedHat based dev containers that can be used to test the scripts.
|
||||||
|
|
||||||
See [CONTRIBUTING.md](../CONTRIBUTING.md) for details on contributing definitions to this repository.
|
|
||||||
|
|
||||||
## Scripts
|
## Scripts
|
||||||
|
|
||||||
- `common-debian.sh`, `common-alpine.sh`, `common-redhat.sh` - Installs common packages and utilities, creates a non-root user, and optionally upgrades packages, and installs zsh and Oh My Zsh!
|
Script names end in the Linux distribution "tree" they support.
|
||||||
- `docker-debian.sh`, `docker-redhat.sh` - Installs the Docker CLI and wires up a script that can enable non-root access to the Docker socket. See [Docker from Docker](../containers/docker-from-docker) for an example. Generally assumes `common-debian.sh` has been run.
|
|
||||||
- `node-debian.sh` - Installs the [Node Version Manager](https://github.com/nvm-sh/nvm) (nvm), the specified version of Node.js (if any) using nvm, ensures the specified non-root user can access everything. See [.NET Core](../containers/dotnet) for an example. Generally assumes `common-debian.sh` has been run.
|
- `-debian` - Debian or Ubuntu
|
||||||
|
- `-redhat` - CentOS, RHEL, Oracle Linux
|
||||||
|
- `-alpine` - Alpine Linux
|
||||||
|
|
||||||
|
| Script | Arguments | Purpose |
|
||||||
|
|--------|---------|-----------|
|
||||||
|
| `common-debian.sh`<br />`common-alpine.sh`<br />`common-redhat.sh` | `[INSTALL ZSH FLAG] [USERNAME] [USER UID] [USER GID] [UPGRADE PACKAGES FLAG]`<br /><br /> Defaults to `true vscode 1000 1000 true`. Set `USERNAME` to `none` to skip setting up a non-root user. | Installs common packages and utilities, creates a non-root user, and optionally upgrades packages, and installs zsh and Oh My Zsh! |
|
||||||
|
| `docker-debian.sh`<br />`docker-redhat.sh` | `[ENABLE NON-ROOT ACCESS] [SOURCE SOCKET] [TARGET SOCKET] [USERNAME]`<br /><br /> Defaults to `true /var/run/docker-host.sock /var/run/docker.sock vscode`. Only sets up `USERNAME` if the user exists on the system.| Installs the Docker CLI and wires up a script that can enable non-root access to the Docker socket. See the [docker-from-docker](../containers/docker-from-docker) definition for an example. |
|
||||||
|
| `node-debian.sh` | `[NVM INSTALL DIRECTORY] [NODE VERSION TO INSTALL] [USERNAME]`<br /><br />Defaults to `/usr/local/share/nvm lts/* vscode`. Only sets up `USERNAME` if the user exists on the system. | Installs the [Node Version Manager](https://github.com/nvm-sh/nvm) (nvm), the specified version of Node.js (if any) using nvm, ensures the specified non-root user can access everything. See the [dotnetcore](../containers/dotnetcore) definition for an example. |
|
||||||
|
| `maven-debian.sh` | `<MAVEN VERSION> [MAVEN INSTALL DIRECTORY] [USERNAME] [DOWNLOAD SHA512]`<br /><br />`MAVEN VERSION` is required. Other arguments default to `/usr/local/share/maven vscode dev-mode`. Only sets up `USERNAME` if the user exists on the system. Download checksum is skipped if set to `dev-mode`. | Installs [Apache Maven](https://github.com/nvm-sh/nvm) and ensures the specified non-root user can access everything. See the [java](../containers/java) definition for an example. |
|
||||||
|
| `gradle-debian.sh` | `<GRADLE VERSION> [GRADLE INSTALL DIRECTORY] [USERNAME] [DOWNLOAD SHA256]`<br /><br />`GRADLE VERSION` is required. Other arguments default to `/usr/local/share/gradle vscode no-check`. Only sets up `USERNAME` if the user exists on the system. Download checksum is skipped if set to `no-check`. | Installs the [Gradle](https://github.com/nvm-sh/nvm) and ensures the specified non-root user can access everything. See the [java](../containers/java) definition for an example. |
|
||||||
|
|
||||||
## Using a script
|
## Using a script
|
||||||
|
|
||||||
|
|
||||||
### Copying the script to .devcontainer/library-scripts
|
### Copying the script to .devcontainer/library-scripts
|
||||||
|
|
||||||
The easiest way to use a script is to simply copy it into a `.devcontainers/library-scripts` folder. From here you can then use the script as follows in your `Dockerfile`:
|
The easiest way to use a script is to simply copy it into a `.devcontainers/library-scripts` folder. From here you can then use the script as follows in your `Dockerfile`:
|
||||||
|
@ -23,17 +30,22 @@ The easiest way to use a script is to simply copy it into a `.devcontainers/libr
|
||||||
|
|
||||||
```Dockerfile
|
```Dockerfile
|
||||||
COPY library-scripts/*.sh /tmp/library-scripts/
|
COPY library-scripts/*.sh /tmp/library-scripts/
|
||||||
RUN apt-get update \
|
RUN /tmp/library-scripts/common-debian.sh
|
||||||
&& /bin/bash /tmp/library-scripts/common-debian.sh \
|
```
|
||||||
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts
|
|
||||||
|
Generally it's also good to clean up after running a script in the same `RUN` statement to keep the "layer" small.
|
||||||
|
|
||||||
|
```Dockerfile
|
||||||
|
COPY library-scripts/*.sh /tmp/library-scripts/
|
||||||
|
RUN /tmp/library-scripts/common-debian.sh
|
||||||
|
&& apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts
|
||||||
```
|
```
|
||||||
|
|
||||||
**Alpine**
|
**Alpine**
|
||||||
|
|
||||||
```Dockerfile
|
```Dockerfile
|
||||||
COPY library-scripts/*.sh /tmp/library-scripts/
|
COPY library-scripts/*.sh /tmp/library-scripts/
|
||||||
RUN apk update \
|
RUN /bin/ash /tmp/library-scripts/common-alpine.sh \
|
||||||
&& /bin/ash /tmp/library-scripts/common-alpine.sh \
|
|
||||||
&& rm -rf /tmp/library-scripts
|
&& rm -rf /tmp/library-scripts
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -45,22 +57,27 @@ RUN /bin/bash /tmp/library-scripts/common-redhat.sh \
|
||||||
&& yum clean all && rm -rf /tmp/library-scripts
|
&& yum clean all && rm -rf /tmp/library-scripts
|
||||||
```
|
```
|
||||||
|
|
||||||
The last line is technically optional, but minimizes the size of the layer by removing temporary contents.
|
Note that the CI process for this repository will automatically keep scripts in the `.devcontainers/library-scripts` folder up to date for each definition in the `containers` folder.
|
||||||
|
|
||||||
The CI process for this repository will automatically keep scripts in the `.devcontainers/library-scripts` folder up to date for each definition in the `containers` folder.
|
|
||||||
|
|
||||||
### Downloading the script with curl instead
|
### Downloading the script with curl instead
|
||||||
|
|
||||||
If you prefer, you can download the script using `curl` or `wget` and execute it instead. This can convienent to do with your own `Dockerfile`, but is generally avoided for definitions in this repository. To avoid unexpected issues, you should reference a release specific version of the script, rather than using master. For example:
|
If you prefer, you can download the script using `curl` or `wget` and execute it instead. This can convenient to do with your own `Dockerfile`, but is generally avoided for definitions in this repository. To avoid unexpected issues, you should reference a release specific version of the script, rather than using master. For example:
|
||||||
|
|
||||||
|
```Dockerfile
|
||||||
|
RUN curl -sSL -o- "https://github.com/microsoft/vscode-dev-containers/blob/v0.131.0/script-library/common-debian.sh" | bash -
|
||||||
|
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*
|
||||||
|
```
|
||||||
|
|
||||||
|
Or if you're not sure if `curl` is installed:
|
||||||
|
|
||||||
```Dockerfile
|
```Dockerfile
|
||||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||||
&& apt-get -y install --no-install-recommends curl ca-certificates \
|
&& apt-get -y install --no-install-recommends curl ca-certificates \
|
||||||
&& curl -sSL -o- "https://github.com/microsoft/vscode-dev-containers/blob/v0.131.0/script-library/common-debian.sh" | bash - \
|
&& curl -sSL -o- "https://github.com/microsoft/vscode-dev-containers/blob/v0.131.0/script-library/common-debian.sh" | bash - \
|
||||||
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
|
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*
|
||||||
```
|
```
|
||||||
|
|
||||||
The last line is technically optional, but minimizes the size of the layer by removing temporary contents.
|
As before, the last line is technically optional, but minimizes the size of the layer by removing temporary contents.
|
||||||
|
|
||||||
### Arguments
|
### Arguments
|
||||||
|
|
||||||
|
@ -75,9 +92,8 @@ In this case, you can simply pass in the arguments to the script.
|
||||||
ARG INSTALL_ZSH="true"
|
ARG INSTALL_ZSH="true"
|
||||||
|
|
||||||
COPY library-scripts/*.sh /tmp/library-scripts/
|
COPY library-scripts/*.sh /tmp/library-scripts/
|
||||||
RUN apt-get update \
|
RUN /bin/bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "vscode" "1000" "1000" "true" \
|
||||||
&& /bin/bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "vscode" "1000" "1000" "true" \
|
&& apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts
|
||||||
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Using arguments when downloading with curl
|
#### Using arguments when downloading with curl
|
||||||
|
@ -92,43 +108,12 @@ ARG INSTALL_ZSH="true"
|
||||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||||
&& apt-get -y install --no-install-recommends curl ca-certificates \
|
&& apt-get -y install --no-install-recommends curl ca-certificates \
|
||||||
&& curl -sSL -o- "https://github.com/microsoft/vscode-dev-containers/blob/v0.131.0/script-library/common-debian.sh" | bash -s -- "${INSTALL_ZSH}" "vscode" "1000" "1000" "true" \
|
&& curl -sSL -o- "https://github.com/microsoft/vscode-dev-containers/blob/v0.131.0/script-library/common-debian.sh" | bash -s -- "${INSTALL_ZSH}" "vscode" "1000" "1000" "true" \
|
||||||
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
|
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*
|
||||||
```
|
```
|
||||||
|
|
||||||
### [Optional] Validating a file's checksum for security when using curl
|
## Contributing
|
||||||
|
|
||||||
If for some reason you cannot copy the script you want to use into the `.devcontainer/library-scripts` folder, you can improve security using a checksum. The CI process will automatically generate a checksum on release if you add two related `ARG`s that end in `_SCRIPT_SOURCE` and `_SCRIPT_SHA`.
|
See [CONTRIBUTING.md](../CONTRIBUTING.md) for details on contributing definitions to this repository.
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
```Dockerfile
|
|
||||||
# Options for script
|
|
||||||
ARG INSTALL_ZSH="true"
|
|
||||||
|
|
||||||
# Script source
|
|
||||||
ARG COMMON_SCRIPT_SOURCE="https://github.com/microsoft/vscode-dev-containers/blob/v0.131.0/script-library/common-debian.sh"
|
|
||||||
ARG COMMON_SCRIPT_SHA="dev-mode"
|
|
||||||
|
|
||||||
# Download script, validate its checksum, and run it with the options above
|
|
||||||
RUN apt-get update \
|
|
||||||
&& export DEBIAN_FRONTEND=noninteractive \
|
|
||||||
&& apt-get -y install --no-install-recommends curl ca-certificates 2>&1 \
|
|
||||||
&& curl -sSL ${COMMON_SCRIPT_SOURCE} -o /tmp/common-setup.sh \
|
|
||||||
&& ([ "${COMMON_SCRIPT_SHA}" = "dev-mode" ] || (echo "${COMMON_SCRIPT_SHA} */tmp/common-setup.sh" | sha256sum -c -)) \
|
|
||||||
&& /bin/bash /tmp/common-setup.sh "${INSTALL_ZSH}" "vscode" "1000" "1000" "true" \
|
|
||||||
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/common-setup.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
When a release is created, the SHA will be automatically added to the tagged source code. e.g. in v1.30.0, these updates are applied:
|
|
||||||
|
|
||||||
```Dockerfile
|
|
||||||
ARG COMMON_SCRIPT_SOURCE="https://raw.githubusercontent.com/microsoft/vscode-dev-containers/v0.130.0/script-library/common-debian.sh"
|
|
||||||
ARG COMMON_SCRIPT_SHA="a6bfacc5c9c6c3706adc8788bf70182729767955b7a5509598ac205ce6847e1e"
|
|
||||||
```
|
|
||||||
|
|
||||||
This locks the version of the script to v1.30.0 and will verify that the script has not been modified before running it.
|
|
||||||
|
|
||||||
Check out the [v1.30.0 tag for the Ubuntu definition](https://github.com/microsoft/vscode-dev-containers/blob/v0.130.0/containers/ubuntu/.devcontainer/base.Dockerfile) to see a real world example of the script doing this for you.
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
|
@ -6,15 +6,15 @@
|
||||||
|
|
||||||
# Syntax: ./common-alpine.sh <install zsh flag> <username> <user UID> <user GID>
|
# Syntax: ./common-alpine.sh <install zsh flag> <username> <user UID> <user GID>
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
INSTALL_ZSH=${1:-"true"}
|
INSTALL_ZSH=${1:-"true"}
|
||||||
USERNAME=${2:-"$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)"}
|
USERNAME=${2:-"$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)"}
|
||||||
USER_UID=${3:-1000}
|
USER_UID=${3:-1000}
|
||||||
USER_GID=${4:-1000}
|
USER_GID=${4:-1000}
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
if [ "$(id -u)" -ne 0 ]; then
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
echo 'Script must be run a root. Use sudo or set "USER root" before running the script.'
|
echo -e 'Script must be run a root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -4,28 +4,18 @@
|
||||||
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
|
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
|
||||||
#-------------------------------------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
# Syntax: ./common-debian.sh <install zsh flag> <username> <user UID> <user GID> <upgrade packages flag>
|
# Syntax: ./common-debian.sh [install zsh flag] [username] [user UID] [user GID] [upgrade packages flag]
|
||||||
|
|
||||||
apt-get-update-if-needed()
|
|
||||||
{
|
|
||||||
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
|
|
||||||
echo "Running apt-get update..."
|
|
||||||
apt-get update
|
|
||||||
else
|
|
||||||
echo "Skipping apt-get update."
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
INSTALL_ZSH=${1:-"true"}
|
INSTALL_ZSH=${1:-"true"}
|
||||||
USERNAME=${2:-"$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)"}
|
USERNAME=${2:-"vscode"}
|
||||||
USER_UID=${3:-1000}
|
USER_UID=${3:-1000}
|
||||||
USER_GID=${4:-1000}
|
USER_GID=${4:-1000}
|
||||||
UPGRADE_PACKAGES=${5:-"true"}
|
UPGRADE_PACKAGES=${5:-"true"}
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
if [ "$(id -u)" -ne 0 ]; then
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
echo 'Script must be run a root. Use sudo or set "USER root" in your Dockerfile before running the script.'
|
echo -e 'Script must be run a root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -47,6 +37,17 @@ fi
|
||||||
# Ensure apt is in non-interactive to avoid prompts
|
# Ensure apt is in non-interactive to avoid prompts
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
# Function to call apt-get if needed
|
||||||
|
apt-get-update-if-needed()
|
||||||
|
{
|
||||||
|
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
|
||||||
|
echo "Running apt-get update..."
|
||||||
|
apt-get update
|
||||||
|
else
|
||||||
|
echo "Skipping apt-get update."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Run install apt-utils to avoid debconf warning then verify presence of other common developer tools and dependencies
|
# Run install apt-utils to avoid debconf warning then verify presence of other common developer tools and dependencies
|
||||||
if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then
|
if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then
|
||||||
apt-get-update-if-needed
|
apt-get-update-if-needed
|
||||||
|
@ -132,10 +133,10 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Add add sudo support for non-root user
|
# Add add sudo support for non-root user
|
||||||
if [ "${NON_ROOT_USER}" != "${USERNAME}" ]; then
|
if [ "${EXISTING_NON_ROOT_USER}" != "${USERNAME}" ]; then
|
||||||
echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME
|
echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME
|
||||||
chmod 0440 /etc/sudoers.d/$USERNAME
|
chmod 0440 /etc/sudoers.d/$USERNAME
|
||||||
NON_ROOT_USER="${USERNAME}"
|
EXISTING_NON_ROOT_USER="${USERNAME}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Ensure ~/.local/bin is in the PATH for root and non-root users for bash. (zsh is later)
|
# Ensure ~/.local/bin is in the PATH for root and non-root users for bash. (zsh is later)
|
||||||
|
@ -149,12 +150,14 @@ fi
|
||||||
if [ "${INSTALL_ZSH}" = "true" ] && [ ! -d "/root/.oh-my-zsh" ] && [ "${ZSH_ALREADY_INSTALLED}" != "true" ]; then
|
if [ "${INSTALL_ZSH}" = "true" ] && [ ! -d "/root/.oh-my-zsh" ] && [ "${ZSH_ALREADY_INSTALLED}" != "true" ]; then
|
||||||
apt-get-update-if-needed
|
apt-get-update-if-needed
|
||||||
apt-get install -y zsh
|
apt-get install -y zsh
|
||||||
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
|
curl -fsSLo- https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh | bash 2>&1
|
||||||
echo "export PATH=\$PATH:\$HOME/.local/bin" >> /root/.zshrc
|
echo "export PATH=\$PATH:\$HOME/.local/bin" >> /root/.zshrc
|
||||||
cp -R /root/.oh-my-zsh /home/$USERNAME
|
if [ "${USERNAME}" != "root" ]; then
|
||||||
cp /root/.zshrc /home/$USERNAME
|
cp -fR /root/.oh-my-zsh /home/$USERNAME
|
||||||
sed -i -e "s/\/root\/.oh-my-zsh/\/home\/$USERNAME\/.oh-my-zsh/g" /home/$USERNAME/.zshrc
|
cp -f /root/.zshrc /home/$USERNAME
|
||||||
chown -R $USER_UID:$USER_GID /home/$USERNAME/.oh-my-zsh /home/$USERNAME/.zshrc
|
sed -i -e "s/\/root\/.oh-my-zsh/\/home\/$USERNAME\/.oh-my-zsh/g" /home/$USERNAME/.zshrc
|
||||||
|
chown -R $USER_UID:$USER_GID /home/$USERNAME/.oh-my-zsh /home/$USERNAME/.zshrc
|
||||||
|
fi
|
||||||
ZSH_ALREADY_INSTALLED="true"
|
ZSH_ALREADY_INSTALLED="true"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -163,6 +166,6 @@ mkdir -p "$(dirname "${MARKER_FILE}")"
|
||||||
echo -e "\
|
echo -e "\
|
||||||
PACKAGES_ALREADY_INSTALLED=${PACKAGES_ALREADY_INSTALLED}\n\
|
PACKAGES_ALREADY_INSTALLED=${PACKAGES_ALREADY_INSTALLED}\n\
|
||||||
LOCALE_ALREADY_SET=${LOCALE_ALREADY_SET}\n\
|
LOCALE_ALREADY_SET=${LOCALE_ALREADY_SET}\n\
|
||||||
NON_ROOT_USER=${NON_ROOT_USER}\n\
|
EXISTING_NON_ROOT_USER=${EXISTING_NON_ROOT_USER}\n\
|
||||||
DOT_LOCAL_ALREADY_ADDED=${DOT_LOCAL_ALREADY_ADDED}\n\
|
DOT_LOCAL_ALREADY_ADDED=${DOT_LOCAL_ALREADY_ADDED}\n\
|
||||||
ZSH_ALREADY_INSTALLED=${ZSH_ALREADY_INSTALLED}" > "${MARKER_FILE}"
|
ZSH_ALREADY_INSTALLED=${ZSH_ALREADY_INSTALLED}" > "${MARKER_FILE}"
|
||||||
|
|
|
@ -6,16 +6,16 @@
|
||||||
|
|
||||||
# Syntax: ./common-redhat.sh <install zsh flag> <username> <user UID> <user GID>
|
# Syntax: ./common-redhat.sh <install zsh flag> <username> <user UID> <user GID>
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
INSTALL_ZSH=${1:-"true"}
|
INSTALL_ZSH=${1:-"true"}
|
||||||
USERNAME=${2:-"$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)"}
|
USERNAME=${2:-"$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)"}
|
||||||
USER_UID=${3:-1000}
|
USER_UID=${3:-1000}
|
||||||
USER_GID=${4:-1000}
|
USER_GID=${4:-1000}
|
||||||
UPGRADE_PACKAGES=${5:-true}
|
UPGRADE_PACKAGES=${5:-true}
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
if [ "$(id -u)" -ne 0 ]; then
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
echo 'Script must be run a root. Use sudo or set "USER root" before running the script.'
|
echo -e 'Script must be run a root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ chown $USER_UID:$USER_GID /home/$USERNAME/.bashrc
|
||||||
# Optionally install and configure zsh
|
# Optionally install and configure zsh
|
||||||
if [ "$INSTALL_ZSH" = "true" ] && [ ! -d "/root/.oh-my-zsh" ]; then
|
if [ "$INSTALL_ZSH" = "true" ] && [ ! -d "/root/.oh-my-zsh" ]; then
|
||||||
yum install -y zsh
|
yum install -y zsh
|
||||||
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
|
curl -fsSLo- https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh | bash 2>&1
|
||||||
echo "export PATH=\$PATH:\$HOME/.local/bin" >> /root/.zshrc
|
echo "export PATH=\$PATH:\$HOME/.local/bin" >> /root/.zshrc
|
||||||
cp -R /root/.oh-my-zsh /home/$USERNAME
|
cp -R /root/.oh-my-zsh /home/$USERNAME
|
||||||
cp /root/.zshrc /home/$USERNAME
|
cp /root/.zshrc /home/$USERNAME
|
||||||
|
|
|
@ -6,6 +6,22 @@
|
||||||
|
|
||||||
# Syntax: ./docker-debian.sh <enable non-root docker socket access flag> <source socket> <target socket> <non-root user>
|
# Syntax: ./docker-debian.sh <enable non-root docker socket access flag> <source socket> <target socket> <non-root user>
|
||||||
|
|
||||||
|
ENABLE_NONROOT_DOCKER=${1:-"true"}
|
||||||
|
SOURCE_SOCKET=${2:-"/var/run/docker-host.sock"}
|
||||||
|
TARGET_SOCKET=${3:-"/var/run/docker.sock"}
|
||||||
|
USERNAME=${4:-"vscode"}
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
|
echo -e 'Script must be run a root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure apt is in non-interactive to avoid prompts
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
# Function to run apt-get if needed
|
||||||
apt-get-update-if-needed()
|
apt-get-update-if-needed()
|
||||||
{
|
{
|
||||||
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
|
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
|
||||||
|
@ -16,23 +32,10 @@ apt-get-update-if-needed()
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
ENABLE_NONROOT_DOCKER=${1:-"true"}
|
|
||||||
SOURCE_SOCKET=${2:-"/var/run/docker-host.sock"}
|
|
||||||
TARGET_SOCKET=${3:-"/var/run/docker.sock"}
|
|
||||||
NONROOT_USER=${4:-"vscode"}
|
|
||||||
|
|
||||||
if [ "$(id -u)" -ne 0 ]; then
|
|
||||||
echo 'Script must be run a root. Use sudo or set "USER root" in your Dockerfile before running the script.'
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Ensure apt is in non-interactive to avoid prompts
|
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
|
||||||
|
|
||||||
# Install Docker CLI if not already installed
|
# Install Docker CLI if not already installed
|
||||||
if ! type docker > /dev/null 2>&1; then
|
if type docker > /dev/null 2>&1; then
|
||||||
|
echo "Docker CLI already installed."
|
||||||
|
else
|
||||||
if ! type curl > /dev/null 2>&1; then
|
if ! type curl > /dev/null 2>&1; then
|
||||||
apt-get-update-if-needed
|
apt-get-update-if-needed
|
||||||
apt-get -y install --no-install-recommends apt-transport-https ca-certificates curl gnupg2 lsb-release
|
apt-get -y install --no-install-recommends apt-transport-https ca-certificates curl gnupg2 lsb-release
|
||||||
|
@ -41,32 +44,41 @@ if ! type docker > /dev/null 2>&1; then
|
||||||
echo "deb [arch=amd64] https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list
|
echo "deb [arch=amd64] https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get -y install --no-install-recommends docker-ce-cli
|
apt-get -y install --no-install-recommends docker-ce-cli
|
||||||
else
|
|
||||||
echo "Docker CLI already installed."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Install Docker Compose if not already installed
|
# Install Docker Compose if not already installed
|
||||||
if ! type docker-compose > /dev/null 2>&1; then
|
if type docker-compose > /dev/null 2>&1; then
|
||||||
|
echo "Docker Compose already installed."
|
||||||
|
else
|
||||||
LATEST_COMPOSE_VERSION=$(curl -sSL "https://api.github.com/repos/docker/compose/releases/latest" | grep -o -P '(?<="tag_name": ").+(?=")')
|
LATEST_COMPOSE_VERSION=$(curl -sSL "https://api.github.com/repos/docker/compose/releases/latest" | grep -o -P '(?<="tag_name": ").+(?=")')
|
||||||
curl -sSL "https://github.com/docker/compose/releases/download/${LATEST_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
curl -sSL "https://github.com/docker/compose/releases/download/${LATEST_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||||
chmod +x /usr/local/bin/docker-compose
|
chmod +x /usr/local/bin/docker-compose
|
||||||
else
|
|
||||||
echo "Docker Compose already installed."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -f "/usr/local/share/docker-init.sh" ]; then
|
# If init file already exists, exit
|
||||||
# By default, make the source and target sockets the same
|
if [ -f "/usr/local/share/docker-init.sh" ]; then
|
||||||
if [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ]; then
|
exit 0
|
||||||
touch "${SOURCE_SOCKET}"
|
fi
|
||||||
ln -s "${SOURCE_SOCKET}" "${TARGET_SOCKET}"
|
|
||||||
chown -h "${NONROOT_USER}" "${TARGET_SOCKET}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If enabling non-root access and specified user is found, setup socat and add script
|
# By default, make the source and target sockets the same
|
||||||
if [ "${ENABLE_NONROOT_DOCKER}" = "true" ] && id -u ${NONROOT_USER} > /dev/null 2>&1; then
|
if [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ]; then
|
||||||
apt-get-update-if-needed
|
touch "${SOURCE_SOCKET}"
|
||||||
apt-get -y install socat
|
ln -s "${SOURCE_SOCKET}" "${TARGET_SOCKET}"
|
||||||
tee /usr/local/share/docker-init.sh << EOF
|
fi
|
||||||
|
|
||||||
|
# Add a stub if not adding non-root user access, user is root, or the specified user does not exist
|
||||||
|
if [ "${ENABLE_NONROOT_DOCKER}" = "false" ] || [ "${USERNAME}" = "root" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
|
||||||
|
echo '/usr/bin/env bash -c "\$@"' > /usr/local/share/docker-init.sh
|
||||||
|
chmod +x /usr/local/share/docker-init.sh
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If enabling non-root access and specified user is found, setup socat and add script
|
||||||
|
chown -h "${USERNAME}":root "${TARGET_SOCKET}"
|
||||||
|
apt-get-update-if-needed
|
||||||
|
apt-get -y install socat
|
||||||
|
tee /usr/local/share/docker-init.sh > /dev/null \
|
||||||
|
<< EOF
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
#-------------------------------------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------------------------------------
|
||||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
@ -96,12 +108,12 @@ log()
|
||||||
}
|
}
|
||||||
|
|
||||||
echo -e "\n** \$(date) **" | sudoIf tee -a \${SOCAT_LOG} > /dev/null
|
echo -e "\n** \$(date) **" | sudoIf tee -a \${SOCAT_LOG} > /dev/null
|
||||||
log "Ensuring ${NONROOT_USER} has access to ${SOURCE_SOCKET} via ${TARGET_SOCKET}"
|
log "Ensuring ${USERNAME} has access to ${SOURCE_SOCKET} via ${TARGET_SOCKET}"
|
||||||
|
|
||||||
# If enabled, try to add a docker group with the right GID. If the group is root,
|
# If enabled, try to add a docker group with the right GID. If the group is root,
|
||||||
# fall back on using socat to forward the docker socket to another unix socket so
|
# fall back on using socat to forward the docker socket to another unix socket so
|
||||||
# that we can set permissions on it without affecting the host.
|
# that we can set permissions on it without affecting the host.
|
||||||
if [ "${ENABLE_NONROOT_DOCKER}" = "true" ] && [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ] && [ "${NONROOT_USER}" != "root" ] && [ "${NONROOT_USER}" != "0" ]; then
|
if [ "${ENABLE_NONROOT_DOCKER}" = "true" ] && [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ] && [ "${USERNAME}" != "root" ] && [ "${USERNAME}" != "0" ]; then
|
||||||
SOCKET_GID=\$(stat -c '%g' ${SOURCE_SOCKET})
|
SOCKET_GID=\$(stat -c '%g' ${SOURCE_SOCKET})
|
||||||
if [ "\${SOCKET_GID}" != "0" ]; then
|
if [ "\${SOCKET_GID}" != "0" ]; then
|
||||||
log "Adding user to group with GID \${SOCKET_GID}."
|
log "Adding user to group with GID \${SOCKET_GID}."
|
||||||
|
@ -109,8 +121,8 @@ if [ "${ENABLE_NONROOT_DOCKER}" = "true" ] && [ "${SOURCE_SOCKET}" != "${TARGET_
|
||||||
sudoIf groupadd --gid \${SOCKET_GID} docker-host
|
sudoIf groupadd --gid \${SOCKET_GID} docker-host
|
||||||
fi
|
fi
|
||||||
# Add user to group if not already in it
|
# Add user to group if not already in it
|
||||||
if [ "\$(id ${NONROOT_USER} | grep -E 'groups=.+\${SOCKET_GID}\(')" = "" ]; then
|
if [ "\$(id ${USERNAME} | grep -E 'groups=.+\${SOCKET_GID}\(')" = "" ]; then
|
||||||
sudoIf usermod -aG \${SOCKET_GID} ${NONROOT_USER}
|
sudoIf usermod -aG \${SOCKET_GID} ${USERNAME}
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# Enable proxy if not already running
|
# Enable proxy if not already running
|
||||||
|
@ -118,7 +130,7 @@ if [ "${ENABLE_NONROOT_DOCKER}" = "true" ] && [ "${SOURCE_SOCKET}" != "${TARGET_
|
||||||
log "Enabling socket proxy."
|
log "Enabling socket proxy."
|
||||||
log "Proxying ${SOURCE_SOCKET} to ${TARGET_SOCKET} for vscode"
|
log "Proxying ${SOURCE_SOCKET} to ${TARGET_SOCKET} for vscode"
|
||||||
sudoIf rm -rf ${TARGET_SOCKET}
|
sudoIf rm -rf ${TARGET_SOCKET}
|
||||||
(sudoIf socat UNIX-LISTEN:${TARGET_SOCKET},fork,mode=660,user=${NONROOT_USER} UNIX-CONNECT:${SOURCE_SOCKET} 2>&1 | sudoIf tee -a \${SOCAT_LOG} > /dev/null & echo "\$!" | sudoIf tee \${SOCAT_PID} > /dev/null)
|
(sudoIf socat UNIX-LISTEN:${TARGET_SOCKET},fork,mode=660,user=${USERNAME} UNIX-CONNECT:${SOURCE_SOCKET} 2>&1 | sudoIf tee -a \${SOCAT_LOG} > /dev/null & echo "\$!" | sudoIf tee \${SOCAT_PID} > /dev/null)
|
||||||
else
|
else
|
||||||
log "Socket proxy already running."
|
log "Socket proxy already running."
|
||||||
fi
|
fi
|
||||||
|
@ -131,8 +143,5 @@ fi
|
||||||
set +e
|
set +e
|
||||||
"\$@"
|
"\$@"
|
||||||
EOF
|
EOF
|
||||||
else
|
chmod +x /usr/local/share/docker-init.sh
|
||||||
echo '/usr/bin/env bash -c "\$@"' > /usr/local/share/docker-init.sh
|
chown ${USERNAME}:root /usr/local/share/docker-init.sh
|
||||||
fi
|
|
||||||
chmod +x /usr/local/share/docker-init.sh
|
|
||||||
fi
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Syntax: ./docker-redhat.sh <enable non-root docker socket access flag> <source socket> <target socket> <non-root user>
|
# Syntax: ./docker-redhat.sh <enable non-root docker socket access flag> <source socket> <target socket> <non-root user>
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
ENABLE_NONROOT_DOCKER=${1:-"true"}
|
ENABLE_NONROOT_DOCKER=${1:-"true"}
|
||||||
SOURCE_SOCKET=${2:-"/var/run/docker-host.sock"}
|
SOURCE_SOCKET=${2:-"/var/run/docker-host.sock"}
|
||||||
TARGET_SOCKET=${3:-"/var/run/docker.sock"}
|
TARGET_SOCKET=${3:-"/var/run/docker.sock"}
|
||||||
NONROOT_USER=${4:-"vscode"}
|
NONROOT_USER=${4:-"vscode"}
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
if [ "$(id -u)" -ne 0 ]; then
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
echo 'Script must be run a root. Use sudo or set "USER root" before running the script.'
|
echo -e 'Script must be run a root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -67,7 +67,8 @@ fi
|
||||||
# If enabling non-root access, setup socat
|
# If enabling non-root access, setup socat
|
||||||
if [ "${ENABLE_NONROOT_DOCKER}" = "true" ]; then
|
if [ "${ENABLE_NONROOT_DOCKER}" = "true" ]; then
|
||||||
yum -y install socat
|
yum -y install socat
|
||||||
tee /usr/local/share/docker-init.sh << EOF
|
tee /usr/local/share/docker-init.sh \
|
||||||
|
<< EOF
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#-------------------------------------------------------------------------------------------------------------
|
||||||
|
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
|
||||||
|
#-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Syntax: ./gradle-debian.sh <gradle version> [gradle home] [non-root-user] [gradle SHA 256]
|
||||||
|
|
||||||
|
GRADLE_VERSION=$1
|
||||||
|
GRADLE_HOME=${2:-"/usr/local/share/gradle"}
|
||||||
|
USERNAME=${3:-"vscode"}
|
||||||
|
GRADLE_DOWNLOAD_SHA=${4:-"no-check"}
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ -d "${GRADLE_HOME}" ]; then
|
||||||
|
echo "Gradle already installed."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo -e "Required argument missing.\n\ngradle-debian.sh <gradle version> [gradle home] [non-root-user] [gradle SHA 256]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
|
echo -e 'Script must be run a root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Treat a user name of "none" or non-existant user as root
|
||||||
|
if [ "${USERNAME}" = "none" ] && ! id -u ${USERNAME} > /dev/null 2>&1; then
|
||||||
|
USERNAME=root
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install curl, apt-get dependencies if missing
|
||||||
|
if ! type curl > /dev/null 2>&1; then
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
|
||||||
|
apt-get update
|
||||||
|
fi
|
||||||
|
apt-get -y install --no-install-recommends ca-certificates curl gnupg2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Function to su if user exists and is not root
|
||||||
|
suIf() {
|
||||||
|
if [ "${USERNAME}" != "root" ]; then
|
||||||
|
su ${USERNAME} -c "$@"
|
||||||
|
else
|
||||||
|
"$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install Gradle
|
||||||
|
echo "Downloading Gradle..."
|
||||||
|
suIf "$(cat \
|
||||||
|
<< EOF
|
||||||
|
mkdir -p /tmp/downloads
|
||||||
|
curl -sSL --output /tmp/downloads/archive-gradle.zip https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip
|
||||||
|
([ "${GRADLE_DOWNLOAD_SHA}" = "no-check" ] || echo "${GRADLE_DOWNLOAD_SHA} */tmp/downloads/archive-gradle.zip" | sha256sum --check - )
|
||||||
|
unzip -q /tmp/downloads/archive-gradle.zip -d /tmp/downloads/
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
mv -f /tmp/downloads/gradle* ${GRADLE_HOME}
|
||||||
|
chown ${USERNAME}:root ${GRADLE_HOME}
|
||||||
|
ln -s ${GRADLE_HOME}/bin/gradle /usr/local/bin/gradle
|
||||||
|
rm -rf /tmp/downloads
|
||||||
|
echo "Done."
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#-------------------------------------------------------------------------------------------------------------
|
||||||
|
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
|
||||||
|
#-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Syntax: ./maven-debian.sh <maven version> [maven home] [non-root user] [maven SHA 512]
|
||||||
|
|
||||||
|
MAVEN_VERSION=$1
|
||||||
|
MAVEN_HOME=${2:-"/usr/local/share/maven"}
|
||||||
|
USERNAME=${3:-"vscode"}
|
||||||
|
MAVEN_DOWNLOAD_SHA=${4:-"no-check"}
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ -d "${MAVEN_HOME}" ]; then
|
||||||
|
echo "Maven already installed."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo -e "Required argument missing.\n\nmaven-debian.sh <maven version> [maven home] [non-root user] [maven SHA 512]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
|
echo -e 'Script must be run a root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Treat a user name of "none" or non-existant user as root
|
||||||
|
if [ "${USERNAME}" = "none" ] && ! id -u ${USERNAME} > /dev/null 2>&1; then
|
||||||
|
USERNAME=root
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install curl, apt-get dependencies if missing
|
||||||
|
if ! type curl > /dev/null 2>&1; then
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
|
||||||
|
apt-get update
|
||||||
|
fi
|
||||||
|
apt-get -y install --no-install-recommends ca-certificates curl gnupg2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Function to su if user exists and is not root
|
||||||
|
suIf() {
|
||||||
|
if [ "${USERNAME}" != "root" ]; then
|
||||||
|
su ${USERNAME} -c "$@"
|
||||||
|
else
|
||||||
|
"$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Creat folder, add maven settings
|
||||||
|
mkdir -p ${MAVEN_HOME} ${MAVEN_HOME}/ref
|
||||||
|
tee ${MAVEN_HOME}/ref/maven-settings.xml > /dev/null \
|
||||||
|
<< EOF
|
||||||
|
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
|
||||||
|
<localRepository>${MAVEN_HOME}/ref/repository</localRepository>
|
||||||
|
</settings>
|
||||||
|
EOF
|
||||||
|
chown -R ${USERNAME}:root ${MAVEN_HOME}
|
||||||
|
|
||||||
|
# Install Maven
|
||||||
|
echo "Downloading Maven..."
|
||||||
|
suIf "$(cat \
|
||||||
|
<< EOF
|
||||||
|
curl -fsSL -o /tmp/maven.tar.gz https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz
|
||||||
|
([ "${MAVEN_DOWNLOAD_SHA}" = "dev-mode" ] || echo "${MAVEN_DOWNLOAD_SHA} */tmp/maven.tar.gz" | sha512sum -c - )
|
||||||
|
tar -xzf /tmp/maven.tar.gz -C ${MAVEN_HOME} --strip-components=1
|
||||||
|
rm -f /tmp/maven.tar.gz
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
ln -s ${MAVEN_HOME}/bin/mvn /usr/local/bin/mvn
|
||||||
|
echo "Done."
|
|
@ -6,24 +6,20 @@
|
||||||
|
|
||||||
# Syntax: ./node-debian.sh <directory to install nvm> <node version to install (use "none" to skip)> <non-root user>
|
# Syntax: ./node-debian.sh <directory to install nvm> <node version to install (use "none" to skip)> <non-root user>
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
export NVM_DIR=${1:-"/usr/local/share/nvm"}
|
export NVM_DIR=${1:-"/usr/local/share/nvm"}
|
||||||
export NODE_VERSION=${2:-"lts/*"}
|
export NODE_VERSION=${2:-"lts/*"}
|
||||||
NONROOT_USER=${3:-"vscode"}
|
USERNAME=${3:-"vscode"}
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
if [ "$(id -u)" -ne 0 ]; then
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
echo 'Script must be run a root. Use sudo or set "USER root" before running the script.'
|
echo -e 'Script must be run a root. Use sudo, su, or add "USER root" to\nyour Dockerfile before running this script.'
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Ensure apt is in non-interactive to avoid prompts
|
# Ensure apt is in non-interactive to avoid prompts
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
if [ "${NODE_VERSION}" = "none" ]; then
|
|
||||||
export NODE_VERSION=
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Install curl, apt-get dependencies if missing
|
# Install curl, apt-get dependencies if missing
|
||||||
if ! type curl > /dev/null 2>&1; then
|
if ! type curl > /dev/null 2>&1; then
|
||||||
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
|
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
|
||||||
|
@ -32,43 +28,76 @@ if ! type curl > /dev/null 2>&1; then
|
||||||
apt-get -y install --no-install-recommends apt-transport-https ca-certificates curl gnupg2
|
apt-get -y install --no-install-recommends apt-transport-https ca-certificates curl gnupg2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Install NVM
|
# Treat a user name of "none" as root
|
||||||
if [ ! -d "${NVM_DIR}" ]; then
|
if [ "${USERNAME}" = "none" ]; then
|
||||||
mkdir -p ${NVM_DIR}
|
USERNAME=root
|
||||||
curl -so- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash 2>&1
|
|
||||||
if [ "${NODE_VERSION}" != "" ]; then
|
|
||||||
/bin/bash -c "source $NVM_DIR/nvm.sh && nvm alias default ${NODE_VERSION}" 2>&1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if id -u $NONROOT_USER > /dev/null 2>&1; then
|
|
||||||
echo -e "export NVM_DIR=\"${NVM_DIR}\"\n\
|
|
||||||
[ -s \"\$NVM_DIR/nvm.sh\" ] && \\. \"\$NVM_DIR/nvm.sh\"\n\
|
|
||||||
[ -s \"\$NVM_DIR/bash_completion\" ] && \\. \"\$NVM_DIR/bash_completion\"" \
|
|
||||||
| tee -a /home/${NONROOT_USER}/.bashrc /home/${NONROOT_USER}/.zshrc >> /root/.zshrc
|
|
||||||
|
|
||||||
echo -e "if [ \"\$(stat -c '%U' \$NVM_DIR)\" != \"${NONROOT_USER}\" ]; then\n\
|
|
||||||
sudo chown -R ${NONROOT_USER}:root \$NVM_DIR\n\
|
|
||||||
fi" | tee -a /root/.bashrc /root/.zshrc /home/${NONROOT_USER}/.bashrc >> /home/${NONROOT_USER}/.zshrc
|
|
||||||
|
|
||||||
chown ${NONROOT_USER}:${NONROOT_USER} /home/${NONROOT_USER}/.bashrc /home/${NONROOT_USER}/.zshrc
|
|
||||||
chown -R ${NONROOT_USER}:root ${NVM_DIR}
|
|
||||||
else
|
|
||||||
echo "Non-root user ${NONROOT_USER} not found. Skipping setup for this user."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "NVM already installed."
|
|
||||||
if [ "${NODE_VERSION}" != "" ]; then
|
|
||||||
nvm install "${NODE_VERSION}"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "${NODE_VERSION}" = "none" ]; then
|
||||||
|
export NODE_VERSION=
|
||||||
|
fi
|
||||||
|
|
||||||
# Install yarn
|
# Install yarn
|
||||||
if ! type yarn > /dev/null 2>&1; then
|
if type yarn > /dev/null 2>&1; then
|
||||||
|
echo "Yarn already installed."
|
||||||
|
else
|
||||||
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - 2>/dev/null
|
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - 2>/dev/null
|
||||||
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
|
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get -y install --no-install-recommends yarn
|
apt-get -y install --no-install-recommends yarn
|
||||||
else
|
|
||||||
echo "Yarn already installed."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Install the specified node version if NVM directory already exists, then exit
|
||||||
|
if [ -d "${NVM_DIR}" ]; then
|
||||||
|
echo "NVM already installed."
|
||||||
|
if [ "${NODE_VERSION}" != "" ]; then
|
||||||
|
suIf "nvm install ${NODE_VERSION}"
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p ${NVM_DIR}
|
||||||
|
|
||||||
|
# Set up non-root user if applicable
|
||||||
|
if [ "${USERNAME}" != "root" ] && id -u $USERNAME > /dev/null 2>&1; then
|
||||||
|
# Add NVM init to non-root user
|
||||||
|
tee -a /home/${USERNAME}/.bashrc /home/${USERNAME}/.zshrc >> /root/.zshrc \
|
||||||
|
<< EOF
|
||||||
|
export NVM_DIR="${NVM_DIR}"
|
||||||
|
[ -s "\$NVM_DIR/nvm.sh" ] && . "\$NVM_DIR/nvm.sh"
|
||||||
|
[ -s "\$NVM_DIR/bash_completion" ] && . "\$NVM_DIR/bash_completion"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Add code to update NVM ownership if UID/GID changes
|
||||||
|
tee -a /root/.bashrc /root/.zshrc /home/${USERNAME}/.bashrc >> /home/${USERNAME}/.zshrc \
|
||||||
|
<<EOF
|
||||||
|
if [ "\$(stat -c '%U' \$NVM_DIR)" != "${USERNAME}" ]; then
|
||||||
|
sudo chown -R ${USERNAME}:root \$NVM_DIR
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Update ownership
|
||||||
|
chown ${USERNAME} ${NVM_DIR} /home/${USERNAME}/.bashrc /home/${USERNAME}/.zshrc
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Function to su if user exists and is not root
|
||||||
|
suIf() {
|
||||||
|
if [ "${USERNAME}" != "root" ] && id -u ${USERNAME} > /dev/null 2>&1; then
|
||||||
|
su ${USERNAME} -c "$@"
|
||||||
|
else
|
||||||
|
"$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run NVM installer as non-root if needed
|
||||||
|
suIf "$(cat \
|
||||||
|
<< EOF
|
||||||
|
curl -so- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
|
||||||
|
if [ "${NODE_VERSION}" != "" ]; then
|
||||||
|
source $NVM_DIR/nvm.sh
|
||||||
|
nvm alias default ${NODE_VERSION}
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
)" 2>&1
|
||||||
|
|
||||||
|
|
|
@ -3,36 +3,18 @@
|
||||||
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
|
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
|
||||||
#-------------------------------------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Test defaults
|
||||||
ARG IMAGE_TO_TEST=debian:10
|
ARG IMAGE_TO_TEST=debian:10
|
||||||
FROM ${IMAGE_TO_TEST}
|
FROM ${IMAGE_TO_TEST}
|
||||||
|
|
||||||
ARG DISTRO="debian"
|
|
||||||
ARG USERNAME="vscode"
|
|
||||||
ARG INSTALL_DOCKER="true"
|
|
||||||
ARG UPGRADE_PACKAGES="true"
|
|
||||||
|
|
||||||
COPY *.sh /tmp/
|
COPY *.sh /tmp/
|
||||||
|
COPY test/*.sh /tmp
|
||||||
RUN chmod +x /tmp/*.sh
|
RUN chmod +x /tmp/*.sh
|
||||||
|
|
||||||
# Run common script
|
ARG DISTRO="debian"
|
||||||
RUN /tmp/common-${DISTRO}.sh true ${USERNAME} 1000 1000 ${UPGRADE_PACKAGES}
|
ARG USE_DEFAULTS="true"
|
||||||
|
ARG USERNAME="vscode"
|
||||||
|
RUN /tmp/run-scripts.sh /tmp ${DISTRO} ${USE_DEFAULTS} ${USERNAME} false false 10
|
||||||
|
|
||||||
RUN if [ "${DISTRO}" != "alpine" ]; then\
|
|
||||||
# Run Docker script
|
|
||||||
/tmp/docker-${DISTRO}.sh true /var/run/docker-host.sock /var/run/docker.sock ${USERNAME}; \
|
|
||||||
else \
|
|
||||||
echo -e '#!/bin/bash\n"$@"' | tee /usr/local/share/docker-init.sh \
|
|
||||||
&& chown ${USERNAME} /usr/local/share/docker-init.sh \
|
|
||||||
&& chmod +x /usr/local/share/docker-init.sh; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
RUN if [ "${DISTRO}" = "debian" ]; then \
|
|
||||||
# Run Node script
|
|
||||||
/tmp/node-${DISTRO}.sh "/usr/local/share/nvm" 12 ${USERNAME}; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Setting the ENTRYPOINT to docker-init.sh will configure non-root access to
|
|
||||||
# the Docker socket if "overrideCommand": false is set in devcontainer.json.
|
|
||||||
# The script will also execute CMD if you need to alter startup behaviors.
|
|
||||||
ENTRYPOINT [ "/usr/local/share/docker-init.sh" ]
|
ENTRYPOINT [ "/usr/local/share/docker-init.sh" ]
|
||||||
CMD [ "sleep", "infinity" ]
|
CMD [ "sleep", "infinity" ]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "Script Tester",
|
"name": "Script Tester - Alpine",
|
||||||
"build": {
|
"build": {
|
||||||
"dockerfile": "../Dockerfile",
|
"dockerfile": "../Dockerfile",
|
||||||
"context": "../../",
|
"context": "../../",
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
{
|
{
|
||||||
"name": "Script Tester",
|
"name": "Script Tester - Debian",
|
||||||
"build": {
|
"build": {
|
||||||
"dockerfile": "../Dockerfile",
|
"dockerfile": "../Dockerfile",
|
||||||
"context": "../../",
|
"context": "../../",
|
||||||
"args": {
|
"args": {
|
||||||
"IMAGE_TO_TEST": "debian:10",
|
"IMAGE_TO_TEST": "debian:10",
|
||||||
"USERNAME": "vscode",
|
"DISTRO": "debian",
|
||||||
"DISTRO": "debian"
|
"USERNAME": "tester",
|
||||||
|
"USE_DEFAULTS": "false"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"remoteUser": "tester",
|
||||||
"mounts": [ "source=/var/run/docker.sock,target=/var/run/docker-host.sock,type=bind" ],
|
"mounts": [ "source=/var/run/docker.sock,target=/var/run/docker-host.sock,type=bind" ],
|
||||||
"overrideCommand": false,
|
"overrideCommand": true,
|
||||||
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"terminal.integrated.shell.linux": null
|
"terminal.integrated.shell.linux": null
|
||||||
|
@ -18,7 +20,5 @@
|
||||||
|
|
||||||
"extensions": [
|
"extensions": [
|
||||||
"ms-azuretools.vscode-docker"
|
"ms-azuretools.vscode-docker"
|
||||||
],
|
]
|
||||||
|
|
||||||
"remoteUser": "vscode"
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "Script Tester",
|
"name": "Script Tester - RedHat",
|
||||||
"build": {
|
"build": {
|
||||||
"dockerfile": "../Dockerfile",
|
"dockerfile": "../Dockerfile",
|
||||||
"context": "../../",
|
"context": "../../",
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
SCRIPT_DIR=${1-"/tmp"}
|
||||||
|
DISTRO=${2:-debian}
|
||||||
|
USE_DEFAULTS=${3:-true}
|
||||||
|
USERNAME=${4:-vscode}
|
||||||
|
UPGRADE_PAGKES=${5:-true}
|
||||||
|
ENABLE_NONROOT=${6:-true}
|
||||||
|
NODE_VERSION=${7:-"lts/*"}
|
||||||
|
MAVEN_VERSION=${8:-"3.6.3"}
|
||||||
|
MAVEN_DOWNLOAD_SHA=${9:-"c35a1803a6e70a126e80b2b3ae33eed961f83ed74d18fcd16909b2d44d7dada3203f1ffe726c17ef8dcca2dcaa9fca676987befeadc9b9f759967a8cb77181c0"}
|
||||||
|
GRADLE_VERSION=${10:-"5.4.1"}
|
||||||
|
GRADLE_DOWNLOAD_SHA=${11:-"7bdbad1e4f54f13c8a78abc00c26d44dd8709d4aedb704d913fb1bb78ac025dc"}
|
||||||
|
|
||||||
|
runScript()
|
||||||
|
{
|
||||||
|
SCRIPT=$1
|
||||||
|
ARGS=$2
|
||||||
|
REQUIRED_PREFIX_ARGS=${3:-""}
|
||||||
|
echo "**** Testing $SCRIPT ****"
|
||||||
|
if [ "${USE_DEFAULTS}" = "true" ]; then
|
||||||
|
echo "Using defaults..."
|
||||||
|
${SCRIPT} ${REQUIRED_PREFIX_ARGS}
|
||||||
|
else
|
||||||
|
echo "Arguments: ${REQUIRED_PREFIX_ARGS} ${ARGS}"
|
||||||
|
${SCRIPT} ${REQUIRED_PREFIX_ARGS} ${ARGS}
|
||||||
|
fi
|
||||||
|
echo "**** Done! ****\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
runScript ${SCRIPT_DIR}/common-${DISTRO}.sh "true ${USERNAME} 1000 1000 ${UPGRADE_PACKAGES}"
|
||||||
|
|
||||||
|
if [ "${DISTRO}" = "debian" ]; then
|
||||||
|
runScript ${SCRIPT_DIR}/node-${DISTRO}.sh "/usr/local/share/nvm ${NODE_VERSION} ${USERNAME}"
|
||||||
|
runScript ${SCRIPT_DIR}/maven-${DISTRO}.sh "/usr/local/share/maven ${USERNAME} ${MAVEN_DOWNLOAD_SHA}" "${MAVEN_VERSION}"
|
||||||
|
runScript ${SCRIPT_DIR}/gradle-${DISTRO}.sh "/usr/local/share/gradle ${USERNAME} ${GRADLE_DOWNLOAD_SHA}" "${GRADLE_VERSION}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run Docker script
|
||||||
|
if [ "${DISTRO}" != "alpine" ]; then
|
||||||
|
runScript /tmp/docker-${DISTRO}.sh "true /var/run/docker-host.sock /var/run/docker.sock ${USERNAME}"
|
||||||
|
else
|
||||||
|
echo '#!/bin/bash\n"$@"' | tee /usr/local/share/docker-init.sh
|
||||||
|
chown ${USERNAME} /usr/local/share/docker-init.sh
|
||||||
|
chmod +x /usr/local/share/docker-init.sh
|
||||||
|
fi
|
Загрузка…
Ссылка в новой задаче