This repository has been archived by the owner on Jun 6, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 549
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add offline apt package cache in kube runtime (#4226)
* squash commit * Update package_cache.md * fix & lint * add fix for nfs, samba, azurefile * fix for 32-bit os * fix * use dpkg -V instead of dpkg -l * fix * fix * skip some uts
- Loading branch information
Showing
11 changed files
with
288 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
## Package Cache | ||
|
||
Some runtime plugins use `apt update` and `apt install ...` to install packages. If the network connection from pai cluster to the apt repository is poor, `apt install` may take a long period of time or fail. | ||
|
||
Since we use kube runtime to initialize the environment before job container, it is possible to use the runtime container as a "cache" of some frequently-needed packages. | ||
|
||
Note: `Package Cache` only stores packages for systems of arch `x64`. | ||
|
||
## How to enable cache for your plugin | ||
|
||
**1. Add packages you want to store cache for in the file [`package_cache_info`](src/package_cache/package_cache_info)**: | ||
|
||
``` | ||
# group_name, os, packages(space-gapped) | ||
# "#" can be used for comments | ||
ssh,ubuntu16.04,openssh-client openssh-server | ||
ssh,ubuntu18.04,openssh-client openssh-server | ||
nfs,ubuntu16.04,nfs-common | ||
nfs,ubuntu18.04,nfs-common | ||
``` | ||
|
||
The first column is `group_name`. One group can contain multiple packages. The second column stands for the OS type. Currently only `ubuntu16.04` and `ubuntu18.04` are supported. The third column is the packages you want to add for the group. The last column is the precommands, which will be executed before gathering packages and it can be left empty. | ||
|
||
**2. In `init.py` of each plugin:** | ||
|
||
```python | ||
from plugins.plugin_utils import try_to_install_by_cache | ||
command = [ | ||
try_to_install_by_cache('<group_name>', fallback_cmds=[ | ||
'<fallback commands>', | ||
]) | ||
] | ||
``` | ||
|
||
`try_to_install_by_cache(group_name, fallback_cmds)` will generate a script to install all packages of a certain group name. It guarantees: | ||
|
||
- If it returns 0, all the packages are installed successfully. | ||
- If it has a non-zero exit code, the package installation has failed. Reasons could be that the required cache is not found or other internal problems. In such case, plugin will executes the `fallback_cmds` instead. You can use `apt-get`, `yum` or other commands to install the packages. | ||
|
||
Here is an example for the `ssh` plugin: | ||
|
||
```python | ||
command = [ | ||
try_to_install_by_cache('ssh', fallback_cmds=[ | ||
'apt-get update', | ||
'apt-get install -y openssh-client openssh-server', | ||
]), | ||
'......' | ||
] | ||
``` | ||
|
||
## Optimization (TBD) | ||
|
||
1. Use hash of package url to save storage space: Packages with the same url can be saved together. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# group_name, os, packages(space-gapped) | ||
# "#" can be used for comments | ||
ssh,ubuntu16.04,openssh-client openssh-server | ||
ssh,ubuntu18.04,openssh-client openssh-server | ||
nfs,ubuntu16.04,nfs-common | ||
nfs,ubuntu18.04,nfs-common | ||
samba,ubuntu16.04,cifs-utils | ||
samba,ubuntu18.04,cifs-utils | ||
azurefile,ubuntu16.04,cifs-utils sshpass | ||
azurefile,ubuntu18.04,cifs-utils sshpass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#!/bin/bash | ||
|
||
# Copyright (c) Microsoft Corporation | ||
# All rights reserved. | ||
# | ||
# MIT License | ||
# | ||
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated | ||
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation | ||
# the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and | ||
# to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
# | ||
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING | ||
# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
||
if [ $# -ne 2 ]; then | ||
echo "Usage: bash -x <this-script.sh> <path-to-package-cache-info> <os-type>" | ||
exit 1 | ||
else | ||
package_cache_info=$1 | ||
os_type=$2 | ||
fi | ||
|
||
apt-get update | ||
ROOT_DIR=/package_cache | ||
mkdir -p $ROOT_DIR | ||
|
||
i=0 | ||
package_dirs=() | ||
|
||
while IFS= read -r line || [[ -n "$line" ]] ; | ||
do | ||
start_char=`echo $line | cut -b 1` | ||
if [ ! "$start_char" == "#" ]; then | ||
name=`echo $line | cut -d , -f 1` | ||
os=`echo $line | cut -d , -f 2` | ||
packages=`echo $line | cut -d , -f 3` | ||
if [ "$os" = "$os_type" ]; then | ||
echo "name: ${name} os: ${os} packages: ${packages}" | ||
package_dir=$ROOT_DIR"/${name}-${os}" | ||
package_dirs[$i]=$package_dir | ||
let i++ | ||
mkdir -p $package_dir | ||
cd $package_dir | ||
echo $packages > ./packages | ||
apt-get -y install --print-uris ${packages} | cut -d " " -f 1-2 | grep http:// > /aptinfo && \ | ||
cat /aptinfo | cut -d\' -f 2 > ./urls && \ | ||
apt-get -y install ${packages} --dry-run &> /dry_run_log && \ | ||
cat /dry_run_log | grep Conf | cut -d " " -f 2 > ./order | ||
if [ $? -ne 0 ]; then | ||
echo 'There is an error during package collection.' | ||
exit 1 | ||
fi | ||
fi | ||
fi | ||
done < $package_cache_info | ||
|
||
apt-get -y install wget | ||
|
||
for package_dir in ${package_dirs[@]};do | ||
cd $package_dir | ||
wget -i ./urls --tries 3 -P ./ && \ | ||
ls -la *.deb | awk '{print $9}' | while read filename; do mv $filename `echo $filename | cut -d "_" -f1`".deb"; done; | ||
if [ $? -ne 0 ]; then | ||
echo 'There is an error during package collection.' | ||
exit 1 | ||
fi | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
#!/bin/bash | ||
|
||
# Copyright (c) Microsoft Corporation | ||
# All rights reserved. | ||
# | ||
# MIT License | ||
# | ||
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated | ||
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation | ||
# the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and | ||
# to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
# | ||
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING | ||
# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
||
PAI_WORK_DIR=/usr/local/pai | ||
CACHE_ROOT_DIR=${PAI_WORK_DIR}/package_cache | ||
|
||
function is_ubuntu_package_installed(){ | ||
for package in $1 | ||
do | ||
dpkg -V $package &> /dev/null | ||
if [ $? -ne 0 ]; then | ||
return 1 | ||
fi | ||
done | ||
return 0 | ||
} | ||
|
||
if [ $# -ne 1 ]; then | ||
echo "Usage: bash -x install_group.sh <group_name>" | ||
exit 1 | ||
else | ||
name=$1 | ||
fi | ||
|
||
if cat /etc/issue | grep "Ubuntu 16.04" &> /dev/null ; then | ||
os='ubuntu16.04' | ||
elif cat /etc/issue | grep "Ubuntu 18.04" &> /dev/null ; then | ||
os='ubuntu18.04' | ||
else | ||
echo "[package_cache] This os doesn't support package cache!" | ||
exit 1 | ||
fi | ||
if [ -d $CACHE_ROOT_DIR"/${name}-${os}" ]; then | ||
package_dir=$CACHE_ROOT_DIR"/${name}-${os}" | ||
packages=`cat ${package_dir}"/packages"` | ||
is_ubuntu_package_installed "${packages}" | ||
if [ $? -eq 0 ]; then | ||
echo "[package_cache] Skip installation of group ${name}." | ||
exit 0 | ||
fi | ||
if [ `getconf LONG_BIT` -eq 64 ]; then | ||
echo "[package_cache] Install group ${name} from cache ${package_dir}." | ||
cat ${package_dir}"/order" | while read file; do dpkg -i ${package_dir}"/"$file".deb"; done; | ||
apt-get install -f | ||
# check if packages are installed | ||
is_ubuntu_package_installed "${packages}" | ||
if [ $? -eq 0 ]; then | ||
echo "[package_cache] Install group ${name} from cache ${package_dir} succeeded!" | ||
else | ||
echo "[package_cache] Install group ${name} from cache ${package_dir} failed. Fallback to apt-get." | ||
apt-get update | ||
apt-get install -y ${packages} | ||
fi | ||
else | ||
echo "[package_cache] 32-Bit OS is not supported! Fallback to apt-get." | ||
apt-get update | ||
apt-get install -y ${packages} | ||
fi | ||
else | ||
echo "Cannot find dependency ${name}-${os}!" | ||
exit 1 | ||
fi |
Oops, something went wrong.