How to automate installation of missing GPG keys on Linux - linux

I've been working with Linux containers for several years. I am surprised that I wasn't able to find a thread about this question. Scenario:
I've just added a new package index (/etc/sources.list.d/example.list) and want to install a package, let's call it snailmail.
I run the commands:
apt-get update && apt-get install -y snailmail
I get the following error:
W: GPG error: https://example.com/snailmail/debian stable InRelease:
The following signatures couldn't be verified because the public key is not available:
NO_PUBKEY 7EF2A9D5F293ECE4
What is the best way to automate the installation of GPG keys?

apt-key now seems to be deprecated, I have created a script that will detect and get the missing keys, you can get it here.
#!/bin/sh -e
tmp="$(mktemp)"
sudo apt-get update 2>&1 | sed -En 's/.*NO_PUBKEY ([[:xdigit:]]+).*/\1/p' | sort -u > "${tmp}"
cat "${tmp}" | xargs sudo gpg --keyserver "hkps://keyserver.ubuntu.com:443" --recv-keys # to /usr/share/keyrings/*
cat "${tmp}" | xargs -L 1 sh -c 'sudo gpg --yes --output "/etc/apt/trusted.gpg.d/$1.gpg" --export "$1"' sh # to /etc/apt/trusted.gpg.d/*
rm "${tmp}"

Here's a handy script that can be called during the build process to download and install common GPG keys (from the Ubuntu keyserver):
Prerequisites:
wget
for PUBKEY in $(apt-get update 2>&1 | grep NO_PUBKEY | awk '{print $NF}')
do
wget -q "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x${PUBKEY}" -O - | sed -n '/BEGIN/,/END/p' | apt-key add - 2>/dev/null
done

Related

What is the idiomatic bash way to echo the executed commands which include pipes and embeded evaluations?

For example, consider the following code (running in an ADO pipeline):
PS4="##[command]"; set -euxo pipefail
wget -qO- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list > /dev/null
The output it produces is pretty confusing:
##[command]gpg --dearmor
##[command]sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
##[command]wget -qO- https://apt.releases.hashicorp.com/gpg
##[command]sudo tee /etc/apt/sources.list.d/hashicorp.list
##[command]]lsb_release -cs
##[command]echo 'deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com focal main'
Is there a better way to do it while keeping it as unobtrusive as it is now? And what is the deal with the ] character in ]lsb_release -cs (line 16) ?

Errors still print to the terminal

I'm writing a bash script here to install docker and send all outputs to the logs.txt file. But i still get errors such as the one below displayed on the terminal, what I'm i doing wrong here to get these errors?
E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?
if [[ `command -v apt-get` ]]; then
echo -e "\n${GREEN}[${WHITE}+${GREENS}]${GREENS} Getting requirements....."
sleep 1;
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release >> logs.txt
echo -e "\n${GREEN}[${WHITE}+${GREENS}]${GREENS} Adding Docker’s official GPG key........"
sleep 1;
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo -e "\n${GREEN}[${WHITE}+${GREENS}]${GREENS} Installing Docker......."
sleep 1;
sudo apt-get install -y docker-ce docker-ce-cli containerd.io >> logs.txt
echo -e "\n${GREEN}[${WHITE}+${GREENS}]${GREENS} Docker version........"
sleep 1;
docker --version | head -n1

Most efficient way to get the latest version of an rpm via web

This is my attempt using wget to pull down the web page, dig for latest tar file and rerun a wget to take it down. In the example, i'm taking down pip.
wget https://pypi.org/project/pip/#files
wget $(grep tar.gz index.html | head -1 | awk -F= '{print $2}' | sed 's/>//' | sed 's/\"//g')
gunzip -c $(ls | grep tar |tail -1) | tar xvf -
yum install -y python-setuptools
cd $(ls -d */ | grep pip)
python setup.py install
cd ..
I'm sure that there is a better way, perhaps only using one wget or similar
Do you mean like that?
wget $(curl -s "https://pypi.org/project/pip/#files"|grep -o 'https://[^"]*tar\.gz')

Installing dotnet Core on Ubuntu 16.04

I am trying to host my ASP.NET-Core WebApi on nginx on my ubuntu system version 16.04.
According to this and this documentation, I should enter the commands:
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
However, the command curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg gives me the following error message:
(23) Failed writing body
Am I doing something wrong, or is the documentation wrong?
Update:
Thank you
Update:
I can execute the following commands:
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-trusty-prod trusty main" > /etc/apt/sources.list.d/dotnetdev.list'
sudo apt-get update
But when I enter sudo apt-get install dotnet-SDK-2.0.0, I am getting the following errors:
Update:

the command apt-get upgrade fails in puppet

I'm running a puppet master and I need to execute these commands on my puppet agent.
Lock kernel from updating
for i in $(dpkg -l "*$(uname -r)*" | grep kernel | awk '{print $2}'); do echo $i hold | dpkg --set-selections; done
Update
apt-get update -y
Upgrade
apt-get upgrade -y
apt-get update -y runs smoothly, but the other two aren't.
Can you give the correct Puppet syntax for this?
exec {'lock kernel from updating':
command => "bash -c 'for i in $(dpkg -l "uname -r" | grep kernel | awk '{print \$2}'); do echo \$i hold | dpkg --set-selections; done'",
}
exec{'update':
command => 'apt-get update -y',
}
exec{'upgrade':
command => 'apt-get upgrade -y',
}

Resources