Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DU Snap and DO Snap integration, change to 'strict' confinement, update docs, and code clean up. #428

Merged
merged 17 commits into from
Mar 16, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,17 @@ set (
"${ADUC_EXTENSIONS_FOLDER}/${ADUC_EXTENSIONS_SUBDIR_DOWNLOAD_HANDLERS}"
CACHE STRING "Path for the download handler extensions")

set (
ADUC_DOWNLOADS_FOLDER
"${ADUC_DATA_FOLDER}/downloads"
CACHE STRING "Path to the folder containing downloaded update artifacts.")
if (ADUC_BUILD_SNAP)
set (
ADUC_DOWNLOADS_FOLDER
/var/lib/deviceupdate-agent-downloads
CACHE STRING "Path to the folder containing downloaded update artifacts.")
else()
set (
ADUC_DOWNLOADS_FOLDER
"${ADUC_DATA_FOLDER}/downloads"
CACHE STRING "Path to the folder containing downloaded update artifacts.")
endif()

set (
ADUC_CONTENT_HANDLERS
Expand Down Expand Up @@ -328,7 +335,7 @@ set (
"adu"
CACHE STRING "The effective group name for adu-shell process.")

if (ADUC_UBUNTU_CORE_SNAP_ONLY)
if (ADUC_BUILD_SNAP)
set (
ADUC_FILE_USER
"root"
Expand Down
40 changes: 33 additions & 7 deletions docs/agent-reference/how-to-build-deviceupdate-agent-snap.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# How To Build the Device Update Agent Snap (for Ubuntu 20.04)

> NOTE: This document is a work-in-progress

## Prerequisites
- Learn about Snapcraft here https://snapcraft.io/docs/getting-started#heading--learning
Expand Down Expand Up @@ -41,6 +40,11 @@ snapcraft

```

## Incremental Build

To rebuild on specific part(s), you can use `snapcraft clean <PART_NAME>` command follow by `snapcraft build` command


### Build Output

If build success, you can find `deviceupdate-agent_#.#_amd64.snap` at the project root directory.
Expand Down Expand Up @@ -69,6 +73,20 @@ sudo snap install --devmode ./deviceupdate-agent_0.1_amd64.snap

> NOTE | This will installs the snap content to /snap/<'snap name'>/ directory on the host device

Although installing and running a snap in dev_mode is useful, it is advisable to test the snap's functionality under strict confinement. This will help verify that all necessary permissions and connections have been correctly configured.

In order to achieve this, the confinement setting should be modified to strict. After rebuilding the snap, it can be installed using the --dangerous option.

For example:

```shell
sudo snap install --dangerous ./deviceupdate-agent_0.1_amd64.snap
```

> NOTE | You can find more information about the --dangerous option and other snap installation options in the official Snapcraft documentation:<br/>
https://snapcraft.io/docs/install-modes#heading--dangerous


## Configure The Device Update Agent Snap

Specify an agent settings, such as, manufacturer, model, agent.name, agent.connectionSource, etc., in `du-config.json`, which localted in `$SNAP_DATA/config` folder.
Expand Down Expand Up @@ -139,32 +157,40 @@ For example:
}
```

> NOTE | Please refer to [Provisioning Device Update Agent Snap](../../snap/local/README.md#provisioning-device-update-agent-snap) for an alternative approach, as the method described earlier may not be effective when using snap in 'strict' confinement.

## Run The Snap
## Run The DU Agent Snap

To run a shell in the confined environment:
To run the "deviceupdate-agent" snap package with elevated privileges (using sudo command) in a Linux-based operating system that supports snap package management, use following command:

```shell
$ sudo snap run deviceupdate-agent
```
To run the "deviceupdate-agent' snap and open a shell environment:

```shell
$ sudo snap run --shell deviceupdate-agent
```

Optionally, copy the prepared `du-config.json` from [host machine] home directory to `$SNAP_DATA/config` directory
When you run the snap run --shell command followed by the name of a snap package, it launches a shell with an environment set up for that specific snap. This allows you to execute commands and access files within the snap package's environment, as if you were running them directly on the host system.

Optionally (for --devmode), copy the prepared `du-config.json` from [host machine] home directory to `$SNAP_DATA/config` directory

```shell
$ cp <home-dir>/du-config.json $SNAP_DATA/config
$ cp /path/to/your/du-config.json $SNAP_DATA/config
```

Inspect some snap variables:

```shell
root@myhost:~# printenv SNAP
/snap/deviceupdate-agent/x2
/snap/deviceupdate-agent/x1

root@myhost:~# printenv SNAP_COMMON
/var/snap/deviceupdate-agent/common

root@myhost:~# printenv SNAP_DATA
/var/snap/deviceupdate-agent/x2
/var/snap/deviceupdate-agent/x1
```

For testing purposes, you can manually run `$SNAP/usr/bin/AducIotAgent -l 0 -e` to verify that the Device Update agent is successfully connected to, and communicated with, the Azure Iot Hub.
Expand Down
24 changes: 18 additions & 6 deletions scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ root_dir=$script_dir/..
build_clean=false
build_documentation=false
build_packages=false
ubuntu_core_snap_only=false;
build_snap=false;
platform_layer="linux"
trace_target_deps=false
content_handlers="microsoft/swupdate,microsoft/apt,microsoft/simulator"
Expand All @@ -42,7 +42,7 @@ log_lib="zlog"
install_prefix=/usr/local
install_adu=false
work_folder=/tmp
cmake_dir_path="${work_folder}/deviceupdate-cmake"
cmake_dir_path=

print_help() {
echo "Usage: build.sh [options...]"
Expand Down Expand Up @@ -78,6 +78,9 @@ print_help() {
echo ""
echo "-u, --ubuntu-core-snap-only Only build components and features those required for the Ubuntu Core snap."
echo ""
echo "--work-folder <work_folder> Specifies the folder where source code will be cloned or downloaded."
echo " Default is /tmp."
echo ""
echo "-h, --help Show this help message."
}

Expand Down Expand Up @@ -274,7 +277,11 @@ while [[ $1 != "" ]]; do
;;
-u | --ubuntu-core-snap-only)
shift
ubuntu_core_snap_only=true
build_snap=true
;;
--work-folder)
shift
work_folder=$(realpath "$1")
;;
-h | --help)
print_help
Expand Down Expand Up @@ -310,12 +317,17 @@ if [[ $adu_log_dir == "" ]]; then
fi

# For ubuntu core snap...
if [[ $ubuntu_core_snap_only == "true" ]]; then
if [[ $build_snap == "true" ]]; then
build_packages=false
fi

runtime_dir=${output_directory}/bin
library_dir=${output_directory}/lib

if [[ "$cmake_dir_path" == "" ]]; then
cmake_dir_path="${work_folder}/deviceupdate-cmake"
fi

cmake_bin="${cmake_dir_path}/bin/cmake"
shellcheck_bin="${work_folder}/deviceupdate-shellcheck"

Expand All @@ -332,7 +344,7 @@ bullet "Logging library: $log_lib"
bullet "Output directory: $output_directory"
bullet "Build unit tests: $build_unittests"
bullet "Build packages: $build_packages"
bullet "Build Ubuntu Core snap features only: $ubuntu_core_snap_only"
bullet "Build Ubuntu Core Snap package: $build_snap"
bullet "CMake: $cmake_bin"
bullet "CMake version: $(${cmake_bin} --version | grep version | awk '{ print $3 }')"
bullet "shellcheck: $shellcheck_bin"
Expand All @@ -359,7 +371,7 @@ CMAKE_OPTIONS=(
"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY:STRING=$library_dir"
"-DCMAKE_RUNTIME_OUTPUT_DIRECTORY:STRING=$runtime_dir"
"-DCMAKE_INSTALL_PREFIX=$install_prefix"
"-DADUC_UBUNTU_CORE_SNAP_ONLY:BOOL=$ubuntu_core_snap_only"
"-DADUC_BUILD_SNAP:BOOL=$build_snap"
)

for i in "${static_analysis_tools[@]}"; do
Expand Down
25 changes: 18 additions & 7 deletions scripts/install-deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ default_do_ref=v1.0.0
install_do=false
do_ref=$default_do_ref

do_cmake_options=(
"-DDO_BUILD_TESTS:BOOL=OFF"
"-DDO_INCLUDE_SDK=ON"
)


# Dependencies packages
aduc_packages=('git' 'make' 'build-essential' 'cmake' 'ninja-build' 'libcurl4-openssl-dev' 'libssl-dev' 'uuid-dev' 'python2.7' 'lsb-release' 'curl' 'wget' 'pkg-config')
static_analysis_packages=('clang' 'clang-tidy' 'cppcheck')
Expand Down Expand Up @@ -125,6 +131,11 @@ print_help() {
echo "--do-commit <commit_sha> Specific commit to fetch."
echo " Default is the latest commit in that branch."
echo ""
echo "--do-cmake-option <option> Additional CMake build option for Delivery Optimiztion."
echo " This option can be specified multiple times."
echo " For example:"
echo " --do-cmake-option '-DDO_BUILD_FOR_SNAP=1' --do-cmake-options '-DDO_BUILD_TESTS'"
echo ""
echo "-p, --install-packages Indicates that packages should be installed."
echo "--install-packages-only Indicates that only packages should be installed and that dependencies should not be installed from source."
echo ""
Expand Down Expand Up @@ -442,9 +453,9 @@ do_install_do() {

local do_url
if [[ $use_ssh == "true" ]]; then
do_url=git@github.com:Microsoft/do-client.git
do_url=git@github.com:microsoft/do-client.git
else
do_url=https://github.com/Microsoft/do-client.git
do_url=https://github.com/microsoft/do-client.git
fi

git clone --recursive --single-branch --branch $do_ref --depth 1 $do_url . || return
Expand All @@ -461,11 +472,6 @@ do_install_do() {
mkdir cmake || return
pushd cmake > /dev/null || return

local do_cmake_options=(
"-DDO_BUILD_TESTS:BOOL=OFF"
"-DDO_INCLUDE_SDK=ON"
)

if [[ $keep_source_code == "true" ]]; then
do_cmake_options+=("-DCMAKE_BUILD_TYPE=Debug")
else
Expand Down Expand Up @@ -820,6 +826,10 @@ while [[ $1 != "" ]]; do
shift
do_ref=$1
;;
--do-cmake-option)
shift
do_cmake_options+=($1)
;;
-p | --install-packages)
install_packages=true
;;
Expand Down Expand Up @@ -861,6 +871,7 @@ if [[ $install_all_deps != "true" && $install_aduc_deps != "true" && \
$install_do != "true" && $install_azure_iot_sdk != "true" && \
$install_catch2 != "true" && $install_swupdate != "true" && \
$install_cmake != "true" && $install_shellcheck != "true" && \
$install_azure_blob_storage_file_upload_utility != "true" && \
$install_githooks != "true" ]]; then
install_all_deps=true
fi
Expand Down
92 changes: 92 additions & 0 deletions snap-commands/set-config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/bin/bash

# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

CONFIG_FILE=""
BASE64_DATA=""
COMMAND_NAME="deviceupdate-agent.set-config"

function show_usage() {

cat << EOS
Usage: $(basename $0) [OPTIONS]

Description:
This script decodes and saves base64 encoded configuration data to a file with the given name in the $SNAP_DATA/config directory.
The script takes two required options - the name of the config file and the base64 encoded data - and saves the data to the specified file.
Only two config file names are allowed: "du-config.json" and "du-diagnostics-config.json".

Options:
-c, --config-file <config file name> Specifies the name of the configuration file to be created or updated.
The only valid values for the config file name are "du-config.json" and "du-diagnostics-config.json".
This option is required.

-d, --data <base64 encoded data> Specifies the base64 encoded configuration data to be saved to the specified config file.
This option is required.

-h, --help Displays this usage information.

Examples:
Save the base64 encoded configuration data to the "du-config.json" file:

$ sudo snap $COMMAND_NAME --config-file du-config.json --data "ABCDEF=="

Save the base64 encoded configuration data to the "du-diagnostics-config.json" file:

$ sudo snap $COMMAND_NAME -c du-diagnostics-config.json -d "UVWXYZ=="
EOS
}

while [[ $# -gt 0 ]]
do
key="$1"

case $key in
-c|--config-file)
CONFIG_FILE="$2"
shift
shift
;;

-d|--data)
BASE64_DATA="$2"
shift
shift
;;

-h|--help)
show_usage
exit 0
;;

*)
echo "Invalid option: $key"
exit 1
;;
esac
done

if [[ -z "$CONFIG_FILE" || -z "$BASE64_DATA" ]]; then
show_usage
exit 1
fi

case $CONFIG_FILE in
du-config.json|du-diagnostics-config.json)
;;
*)
echo -e "Invalid config file name: $CONFIG_FILE\n"
show_usage
exit 1
;;
esac

dst_file="$SNAP_DATA/config/$CONFIG_FILE"

if echo "$BASE64_DATA" | base64 --decode > "$dst_file"; then
echo "Configuration data saved to $dst_file."
else
echo "An error occurred while saving the data."
exit 1
fi
Loading