diff --git a/DEBIAN/control b/DEBIAN/control new file mode 100644 index 0000000..5761cfc --- /dev/null +++ b/DEBIAN/control @@ -0,0 +1,6 @@ +Package: eai-installer +Version: 1.2.3 +Architecture: arm64 +Maintainer: Azure Percept +Description: Microsoft Edge AI Installer + A set of Linux shell scripts to install Percept related Debian packages and also provision user configurations to make the device available to connect with Azure Percept resources. diff --git a/EULA.md b/EULA.md new file mode 100644 index 0000000..1fff422 --- /dev/null +++ b/EULA.md @@ -0,0 +1,81 @@ +## MICROSOFT SOFTWARE LICENSE TERMS +EDGE AI INSTALLER \* +
+ +These license terms are an agreement between you and Microsoft Corporation (or one of its affiliates). They apply to the software named above and any Microsoft services or software updates (except to the extent such services or updates are accompanied by new or additional terms, in which case those different terms apply prospectively and do not alter your or Microsoft’s rights relating to pre-updated software or services). IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW. BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. + +**1. INSTALLATION AND USE RIGHTS.** + + **a) General.** You may install and use any number of copies of the software on your devices. + + **b) Third Party Components.** The software may include third party components with separate legal notices or governed by other agreements, as may be described in the ThirdPartyNotices file(s) accompanying the software. + +**2. SCOPE OF LICENSE.** The software is licensed, not sold. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you will not (and have no right to): + + **a)** work around any technical limitations in the software that only allow you to use it in certain ways; + + **b)** reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software, except and to the extent required by third party licensing terms governing use of certain open source components that may be included in the software; + + **c)** remove, minimize, block, or modify any notices of Microsoft or its suppliers in the software; + + **d)** use the software in any way that is against the law or to create or propagate malware; or + + **e)** share, publish, distribute, or lease the software, provide the software as a stand-alone offering for others to use, or transfer the software or this agreement to any third party. + +**3. PRE-RELEASE SOFTWARE.** The software is a pre-release version. It may not operate correctly. It may be different from the commercially released version. + +**4. FEEDBACK.** If you give feedback about the software to Microsoft, you give to Microsoft, without charge, the right to use, share and commercialize your feedback in any way and for any purpose. You will not give feedback that is subject to a license that requires Microsoft to license its software or documentation to third parties because Microsoft includes your feedback in them. These rights survive this agreement. + +**5. DATA.** + + **a) Data Collection.** The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the product documentation. There are also some features in the software that may enable you to collect data from users of your applications. If you use these features to enable data collection in your applications, you must comply with applicable law, including providing appropriate notices to users of your applications. You can learn more about data collection and use in the help documentation and the privacy statement at [https://aka.ms/privacy](https://aka.ms/privacy). Your use of the software operates as your consent to these practices. + + **b) Processing of Personal Data.** To the extent Microsoft is a processor or subprocessor of personal data in connection with the software, Microsoft makes the commitments in the European Union General Data Protection Regulation Terms of the Online Services Terms to all customers effective May 25, 2018, at [https://docs.microsoft.com/en-us/legal/gdpr](https://docs.microsoft.com/en-us/legal/gdpr). + +**6. EXPORT RESTRICTIONS.** You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit [https://aka.ms/exporting](https://aka.ms/exporting). + +**7. SUPPORT SERVICES.** Microsoft is not obligated under this agreement to provide any support services for the software. Any support provided is “as is”, “with all faults”, and without warranty of any kind. + +**8. ENTIRE AGREEMENT.** This agreement, and any other terms Microsoft may provide for supplements, updates, or third-party applications, is the entire agreement for the software. + +**9. APPLICABLE LAW AND PLACE TO RESOLVE DISPUTES.** If you acquired the software in the United States or Canada, the laws of the state or province where you live (or, if a business, where your principal place of business is located) govern the interpretation of this agreement, claims for its breach, and all other claims (including consumer protection, unfair competition, and tort claims), regardless of conflict of laws principles. If you acquired the software in any other country, its laws apply. If U.S. federal jurisdiction exists, you and Microsoft consent to exclusive jurisdiction and venue in the federal court in King County, Washington for all disputes heard in court. If not, you and Microsoft consent to exclusive jurisdiction and venue in the Superior Court of King County, Washington for all disputes heard in court. + +**10. CONSUMER RIGHTS; REGIONAL VARIATIONS.** This agreement describes certain legal rights. You may have other rights, including consumer rights, under the laws of your state, province, or country. Separate and apart from your relationship with Microsoft, you may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state, province, or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you: + + **a) Australia.** You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights. + + **b) Canada.** If you acquired this software in Canada, you may stop receiving updates by turning off the automatic update feature, disconnecting your device from the Internet (if and when you re-connect to the Internet, however, the software will resume checking for and installing updates), or uninstalling the software. The product documentation, if any, may also specify how to turn off updates for your specific device or software. + + **c) Germany and Austria.** + +  **i. Warranty.** The properly licensed software will perform substantially as described in any Microsoft materials that accompany the software. However, Microsoft gives no contractual guarantee in relation to the licensed software. + +  **ii. Limitation of Liability.** In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as, in case of death or personal or physical injury, Microsoft is liable according to the statutory law. + +  Subject to the foregoing clause ii., Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence. + +**11. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS IS.” YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES, OR CONDITIONS. TO THE EXTENT PERMITTED UNDER APPLICABLE LAWS, MICROSOFT EXCLUDES ALL IMPLIED WARRANTIES, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.** + +**12. LIMITATION ON AND EXCLUSION OF DAMAGES. IF YOU HAVE ANY BASIS FOR RECOVERING DAMAGES DESPITE THE PRECEDING DISCLAIMER OF WARRANTY, YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.** + +**This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, warranty, guarantee, or condition; strict liability, negligence, or other tort; or any other claim; in each case to the extent permitted by applicable law.** + +**It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your state, province, or country may not allow the exclusion or limitation of incidental, consequential, or other damages.** + +**13. CONFIDENTIAL INFORMATION.** The software, including its user interface, features and documentation, is confidential and proprietary to Microsoft and its suppliers. + + **a) Use.** For five years after installation of the software or its commercial release, whichever is first, you may not disclose confidential information to third parties. You may disclose confidential information only to your employees and consultants who need to know the information. You must have written agreements with them that protect the confidential information at least as much as this agreement. + + **b) Survival.** Your duty to protect confidential information survives this agreement. + + **c) Exclusions.** You may disclose confidential information in response to a judicial or governmental order. You must first give written notice to Microsoft to allow it to seek a protective order or otherwise protect the information. Confidential information does not include information that: + +  **i.** becomes publicly known through no wrongful act; + +  **ii.** you received from a third party who did not breach confidentiality obligations to Microsoft or its suppliers; or + +  **iii.** you developed independently. + +
+ +\* Edge AI installer is the placeholder product name and will be updated with the official product name once approved. diff --git a/EULA.pdf b/EULA.pdf new file mode 100644 index 0000000..e1a61c3 Binary files /dev/null and b/EULA.pdf differ diff --git a/MAKESELF/install.sh b/MAKESELF/install.sh new file mode 100755 index 0000000..619610c --- /dev/null +++ b/MAKESELF/install.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +sudo dpkg -i eai-installer_*.deb + +if [ "$?" != "0" ]; +then + echo "************************************************************************" + echo " The installation failed. Please try again..." + echo "************************************************************************" +else + echo "************************************************************************" + echo " Edge AI Installer is installed successfully!" + echo " You can get more details from the help menu:" + echo " $ cd /usr/local/microsoft/eai-installer" + echo " $ sudo ./azure-iot-edge-installer.sh --help" + echo "************************************************************************" +fi diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..3925ada --- /dev/null +++ b/NOTICE @@ -0,0 +1,62 @@ +NOTICES AND INFORMATION +Do Not Translate or Localize + +Edge AI Installer +Copyright 2022 Microsoft + +This software incorporates material from +Azure IoT Edge configuration tool (https://github.com/Azure/iot-edge-config) + +The Initial Developer of the 20.04/dmidecode_3.3-4.debian.tar.xz +is Ubuntu Core Developers (ubuntu-devel-discuss@lists.ubuntu.com) +Copyright: 2003-2007 Petter Reinholdtsen + 2011-2012 Daniel Baumann + 2014-2019 Jörg Frings-Fürst + +--------------------------------------------------------- + +Binary: 20.04/dmidecode_3.3-4_arm64.deb +Source: 20.04/dmidecode_3.3-4.debian.tar.xz +The remainder of source can be downloaded from +Ubuntu Package server (https://packages.ubuntu.com/impish/dmidecode) + +License: GPL-2+ + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see . + . + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-2 file. + +--------------------------------------------------------- + +MIT License + + Copyright (c) Microsoft Corporation. + + 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 diff --git a/src/20.04/dmidecode_3.3-4.debian.tar.xz b/src/20.04/dmidecode_3.3-4.debian.tar.xz new file mode 100644 index 0000000..68e39f3 Binary files /dev/null and b/src/20.04/dmidecode_3.3-4.debian.tar.xz differ diff --git a/src/20.04/dmidecode_3.3-4_arm64.deb b/src/20.04/dmidecode_3.3-4_arm64.deb new file mode 100644 index 0000000..65a54e2 Binary files /dev/null and b/src/20.04/dmidecode_3.3-4_arm64.deb differ diff --git a/src/azure-iot-edge-installer.sh b/src/azure-iot-edge-installer.sh old mode 100644 new mode 100755 index cb1692a..d451d87 --- a/src/azure-iot-edge-installer.sh +++ b/src/azure-iot-edge-installer.sh @@ -12,61 +12,27 @@ then exit 1 fi -VERSION_TAG="v0.0.5" +VERSION_TAG="v$(apt-cache policy eai-installer | grep Installed | cut -d ' ' -f 4)" +if [[ $VERSION_TAG == "v" ]]; +then + VERSION_TAG="unknown" +fi + +# Percept specific packages +declare -a percept_packages=("aziot-identity-service" + "aziot-edge" + "osconfig" + "defender-iot-micro-agent-edge") +declare -a package_versions=("1.4.0-1" + "1.4.0-1" + "1.0.3.2022061604" + "4.2.4") # where am I TOPDIR=$(dirname $0) -###################################### -# download_bash_script -# -# downloads a single bash script from release according to VERSION_TAG -# ARGUMENTS: -# file_name to be downloaded from release -# OUTPUTS: -# Write output to stdout -# RETURN: -###################################### - -function download_bash_script() { - if [[ $# == 1 ]]; - then - local file_name=$1 - local url_text=https://github.com/Azure/iot-edge-config/releases/download/${VERSION_TAG}/$file_name - local tmp_file=$(echo `mktemp -u`) - - printf "attempting to download '%s'.\n" $file_name - - # attempt to download to a temporary file. - # use 'sudo LOCAL_E2E=1 ./azure-iot-edge-installer.sh {}' to validate local source... - if [ "$LOCAL_E2E" == "1" ]; - then - printf "Testing local file '%s'\n" "../$TOPDIR/$file_name" - cp ../$TOPDIR/$file_name . - else - printf "wget '%s' -q -O '%s'\n" $url_text $tmp_file - wget $url_text -q -O $tmp_file - - # validate request - exit_code=$? - if [[ $exit_code != 0 ]]; - then - printf "ERROR: Failed to download '%s'; error: %d\n" $file_name $exit_code - - rm $tmp_file - exit $exit_code - else - printf "downloaded '%s'\n" $file_name - - mv -f $tmp_file $file_name - chmod +x $file_name - fi - fi - fi -} - # script -printf "Welcome to azure-iot-edge-installer\n" +printf "Welcome to azure-iot-edge-installer (${VERSION_TAG})\n" printf "\n%s\n" "-------------------------" printf "Telemetry\n" printf "%s\n" "---------" @@ -76,54 +42,14 @@ printf "The data is collected by Microsoft.\n" printf "You can change your telemetry settings by adding -nt or --telemetry-opt-out to the command line.\n" printf "\n" -# if helper scripts dont exist, fetch via wget -if [ -d "iot-edge-installer" ]; -then - printf "Directory iot-edge-installer already exists.\n" -else - printf "Preparing install directory.\n" - mkdir iot-edge-installer -fi - -cd iot-edge-installer - -printf "Downloading helper files to temporary directory ./iot-edge-installer\n" -download_bash_script validate-tier1-os.sh -download_bash_script install-container-management.sh -download_bash_script install-edge-runtime.sh -download_bash_script validate-post-install.sh -download_bash_script utils.sh -printf "Downloaded helper files to temporary directory ./iot-edge-installer\n" +# setup env +export DEBIAN_FRONTEND=noninteractive # import utils source utils.sh log_init handlers_init -function show_help() { - echo "" - echo "${BOLD}Usage: sudo ./azure-iot-edge-installer.sh [OPTION]...${DEFAULT}" - echo "" - echo "${BOLD}Basic:${DEFAULT}" - echo -e "\t-h, --help\t\t\t\t\tPrint this help" - echo "" - echo "${BOLD}Connection String Provisioning:${DEFAULT}" - echo -e "\t-c, --connection-string \tThe Azure IoT Edge Device Connection String" - echo -e "${MAGENTA}\tThe default provisioning method. For example," - echo -e "\t$ sudo ./azure-iot-edge-installer.sh -c \"\"" - echo -e "${DEFAULT}" - echo "${BOLD}DPS Provisioning:${DEFAULT}" - echo -e "\t-s, --scope-id \t\t\tThe Azure DPS ID Scope" - echo -e "\t-r, --registration-id \t\tThe Azure IoT DPS enrollment Registration ID" - echo -e "\t-k, --symmetric-key \t\tThe Symmetric Key for the individual enrollment" - echo -e "${MAGENTA}\tThree arguments above are all neccessary for DPS provisioning. For example," - echo -e "\t$ sudo ./azure-iot-edge-installer.sh -s -r -k " - echo "${DEFAULT}" - echo "${BOLD}Telemetry:${DEFAULT}" - echo -e "\t-nt, --telemetry-opt-out\t\t\tDisable usage telemetry feature" - echo -e "\t-cv, --correlation-vector\t\t\tCorrelation vector specific to the run\n" -} - # add flag:variable_name dictionary entries add_option_args "TELEMETRY_OPT_OUT" -nt --telemetry-opt-out add_option_args "VERBOSE_LOGGING" -v --verbose @@ -131,8 +57,15 @@ add_option_args "SCOPE_ID" -s --scope-id add_option_args "REGISTRATION_ID" -r --registration-id add_option_args "SYMMETRIC_KEY" -k --symmetric-key add_option_args "CORRELATION_VECTOR" -cv --correlation-vector +add_option_args "FORCE_RUN" -f --force add_option_args "SHOW_HELP" -h --help add_option_args "CONNECTION_STRING" -c --connection-string +add_option_args "HOSTNAME" -hn --hostname +add_option_args "UPGRADE" -u --upgrade +add_option_args "INPUT_FILE" -i --input-file + +# load help menu +source show-help-menu.sh # parse command line inputs and fetch output from parser declare -A parsed_cmds="$(cmd_parser $@)" @@ -141,7 +74,29 @@ declare -A parsed_cmds="$(cmd_parser $@)" if [[ ${#@} == 0 || "${parsed_cmds["SHOW_HELP"]}" != "" ]]; then show_help - exit ${EXIT_CODES[1]} + exit ${EXIT_CODES[0]} +fi + +# show special characters limitation for connection string +if [[ "$@" == *"-c"* || "$@" == *"--connection-string"* ]]; +then + conn_string="${parsed_cmds["CONNECTION_STRING"]}" + device_tmp=${conn_string#*;DeviceId=} + device_id=${device_tmp%;SharedAccessKey=*} + + if [[ ${#@} > 0 && ${#parsed_cmds[*]} == 0 ]] || + [[ "${device_id}" == *"="* || "${device_id}" == *"%"* || "${device_id}" == *"!"* || "${device_id}" == *"$"* ]]; + then + echo "CONNECTION_STRING = \"${conn_string}\"" + echo "" + echo "${YELLOW}Please notice the installer does not support the following special characters for DeviceId in the connection string!" + echo " - equal sign ( = )" + echo " - percent sign ( % )" + echo " - exclamation mark ( ! )" + echo " - dollar sign ( $ )${DEFAULT}" + show_help + exit ${EXIT_CODES[1]} + fi fi # validate that all arguments are acceptable / known @@ -153,26 +108,36 @@ then exit ${EXIT_CODES[1]} fi -# is a connection string given for provisioning? +# upgrade packages +if [[ "${parsed_cmds["UPGRADE"]}" != "" ]]; +then + only_upgrade + exit ${EXIT_CODES[0]} +fi + +# parse input config file +if [[ "${parsed_cmds["INPUT_FILE"]}" != "" ]]; +then + source read-config-file.sh + prepare_json + file_parser ${parsed_cmds["INPUT_FILE"]} +fi + +# check arguments for provisioning +if [[ "${parsed_cmds["INPUT_FILE"]}" == "" ]] || + [[ "${parsed_cmds["INPUT_FILE"]}" != "" && "${parsed_cfgs[{action}{do_provisioning}]}" == "true" ]]; +then if [[ "${parsed_cmds["CONNECTION_STRING"]}" == "" ]]; then - # validate that all DPS parameters have been provided - if [[ "${parsed_cmds["SCOPE_ID"]}" == "" || "${parsed_cmds["REGISTRATION_ID"]}" == "" || "${parsed_cmds["SYMMETRIC_KEY"]}" == "" ]]; - then - echo Missing argument - echo defined: "'"${!parsed_cmds[@]}"'" - echo given: "'"${parsed_cmds[@]}"'" - show_help - exit ${EXIT_CODES[2]} - fi -else - if [[ "${parsed_cmds["CONNECTION_STRING"]}" == "true" ]]; - then - echo Missing argument - echo The IoTEdge device connection string must be provided with the '-c / --connection-string' option - show_help - exit ${EXIT_CODES[2]} - fi +if [[ "${parsed_cmds["SCOPE_ID"]}" == "" || "${parsed_cmds["REGISTRATION_ID"]}" == "" || "${parsed_cmds["SYMMETRIC_KEY"]}" == "" ]]; +then + echo Missing provisioning argument + echo defined: "'"${!parsed_cmds[@]}"'" + echo given: "'"${parsed_cmds[@]}"'" + show_help + exit ${EXIT_CODES[2]} +fi +fi fi set_opt_out_selection ${parsed_cmds["TELEMETRY_OPT_OUT"]} ${parsed_cmds["CORRELATION_VECTOR"]} ${parsed_cmds["SCOPE_ID"]} ${parsed_cmds["REGISTRATION_ID"]} @@ -186,6 +151,11 @@ then exit ${EXIT_CODES[3]} fi +### Installation ### +if [[ "${parsed_cmds["INPUT_FILE"]}" == "" ]] || + [[ "${parsed_cmds["INPUT_FILE"]}" != "" && "${parsed_cfgs[{action}{do_install}]}" == "true" ]]; +then + # run scripts in order, can take parsed input from above platform=$(get_platform) prepare_apt $platform @@ -194,14 +164,57 @@ source install-container-management.sh install_container_management source install-edge-runtime.sh +install_edge_runtime + +source install-percept-packages.sh +install_osconfig +install_defender + +configure_percept_services + +fi + +### Hotfix ### +if [[ "${parsed_cmds["INPUT_FILE"]}" == "" ]] || + [[ "${parsed_cmds["INPUT_FILE"]}" != "" && "${parsed_cfgs[{action}{do_hotfix}]}" == "true" ]]; +then + +source install-hotfix.sh +is_aarch64 +if [ "$?" == "0" ]; +then + # arm64 + install_defender_hotfix +else + # amd64 + log_info "No hotfix is required!" +fi + +fi + +### Provisioning & Configuration ### +source provision-and-configure.sh +if [[ "${parsed_cmds["INPUT_FILE"]}" == "" ]] || + [[ "${parsed_cmds["INPUT_FILE"]}" != "" && "${parsed_cfgs[{action}{do_provisioning}]}" == "true" ]]; +then + +setup_product_info +stop_iotedge_service if [[ "${parsed_cmds["CONNECTION_STRING"]}" == "" ]]; then - install_edge_runtime_dps ${parsed_cmds["SCOPE_ID"]} ${parsed_cmds["REGISTRATION_ID"]} ${parsed_cmds["SYMMETRIC_KEY"]} + setup_hostname ${parsed_cmds["HOSTNAME"]} ${parsed_cmds["REGISTRATION_ID"]} + dps_provisioning ${parsed_cmds["SCOPE_ID"]} ${parsed_cmds["REGISTRATION_ID"]} ${parsed_cmds["SYMMETRIC_KEY"]} else - install_edge_runtime_cs ${parsed_cmds["CONNECTION_STRING"]} + setup_hostname ${parsed_cmds["HOSTNAME"]} ${parsed_cmds["CONNECTION_STRING"]} + cs_provisioning ${parsed_cmds["CONNECTION_STRING"]} +fi + fi +reset_percept_services +### Validation ### source validate-post-install.sh validate_post_install +show_package_version exit ${EXIT_CODES[0]} diff --git a/src/config/default-settings.json b/src/config/default-settings.json new file mode 100644 index 0000000..ccfaa60 --- /dev/null +++ b/src/config/default-settings.json @@ -0,0 +1,7 @@ +{ + "action" : { + "do_install" : true, + "do_hotfix" : true, + "do_provisioning" : true + } +} diff --git a/src/config/hotfix-only.json b/src/config/hotfix-only.json new file mode 100644 index 0000000..5633cb1 --- /dev/null +++ b/src/config/hotfix-only.json @@ -0,0 +1,5 @@ +{ + "action" : { + "do_hotfix" : true + } +} diff --git a/src/config/install-only.json b/src/config/install-only.json new file mode 100644 index 0000000..508b040 --- /dev/null +++ b/src/config/install-only.json @@ -0,0 +1,5 @@ +{ + "action" : { + "do_install" : true + } +} diff --git a/src/config/provision-only.json b/src/config/provision-only.json new file mode 100644 index 0000000..1c6b7ad --- /dev/null +++ b/src/config/provision-only.json @@ -0,0 +1,5 @@ +{ + "action" : { + "do_provisioning" : true + } +} diff --git a/src/install-container-management.sh b/src/install-container-management.sh old mode 100644 new mode 100755 index f45efcb..ccbacbd --- a/src/install-container-management.sh +++ b/src/install-container-management.sh @@ -16,13 +16,13 @@ ###################################### install_container_management() { - if [ -x "$(command -v docker)" ]; + if [ "x$(command -v docker)" != "x" ]; then log_info "docker command is already available." else log_info "Installing moby-engine container management" - apt-get install moby-engine -y 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT & + apt-get install -o Dpkg::Options::="--force-confdef" moby-engine=20.10.17+azure-ubuntu20.04u3 -y 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT & long_running_command $! exit_code=$? if [[ $exit_code != 0 ]]; diff --git a/src/install-edge-runtime.sh b/src/install-edge-runtime.sh old mode 100644 new mode 100755 index 170a7f1..af73ca9 --- a/src/install-edge-runtime.sh +++ b/src/install-edge-runtime.sh @@ -6,160 +6,77 @@ #script to install edge runtime 1.2 ###################################### -# apply_config_changes +# remove_packages # -# - apply changes and restart +# - Remove the installed packages including of +# * IoTEdge +# * OSConfig +# * Defender for IoT # # ARGUMENTS: +# None # OUTPUTS: # Write output to stdout # RETURN: +# updates the global variable OK_TO_CONTINUE in case of success to true. ###################################### -function apply_config_changes() { - log_info "Apply settings - this will restart Azure IoTEdge" - iotedge config apply 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT - exit_code=$? - if [[ $exit_code == 0 ]]; - then - log_info "IoTEdge has been configured successfully" - fi -} +function remove_packages() { + log_info "Removing installed packages..." -###################################### -# install_common -# -# - install the runtime -# -# ARGUMENTS: -# OUTPUTS: -# Write output to stdout -# RETURN: -###################################### - -function install_common() { - log_info "Installing edge runtime..." - - apt-get install aziot-edge -y 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT & + apt-get remove --purge ${percept_packages[@]} -y 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT & long_running_command $! exit_code=$? if [[ $exit_code != 0 ]]; then - log_info "aziot-edged installation failed with exit code: %d" $exit_code + log_info "apt remove failed with exit code: %d" $exit_code exit ${EXIT_CODES[10]} fi - log_info "Installed edge runtime..." + log_info "Removed all packages" } ###################################### -# install_edge_runtime_dps -# -# - installs Azure IoT Edge Runtime 1.2, DPS provisioning -# - generates the edge's configuration file from template and -# fills in the DPS provisioning section from provided parameters -# -# ARGUMENTS: -# SCOPE_ID -# REGISTRATION_ID -# SYMMETRIC_KEY -# OUTPUTS: -# Write output to stdout -# RETURN: -# updates the global variable OK_TO_CONTINUE in case of success to true. -###################################### - -function install_edge_runtime_dps() { - if [[ $# != 3 || "$1" == "" || "$2" == "" || "$3" == "" ]]; - then - log_error "Scope ID, Registration ID, and the Symmetric Key are required" - exit ${EXIT_CODES[2]} - fi - - if [ -x "$(command -v iotedge)" ]; - then - log_error "Edge runtime is already available." - exit ${EXIT_CODES[9]} - fi - - install_common - - # create config.toml - log_info "Create instance configuration 'config.toml'." - - local SCOPE_ID=$1 - local REGISTRATION_ID=$2 - local SYMMETRIC_KEY=$3 - - log_info "Set DPS provisioning parameters." - - local FILE_NAME="/etc/aziot/config.toml" - - # create a config.toml - will replace existing - echo 'hostname = "'`hostname`'"' > $FILE_NAME - echo '' >> $FILE_NAME - echo '## DPS provisioning with symmetric key' >> $FILE_NAME - echo '[provisioning]' >> $FILE_NAME - echo 'source = "dps"' >> $FILE_NAME - echo 'global_endpoint = "https://global.azure-devices-provisioning.net"' >> $FILE_NAME - echo 'id_scope = "'$SCOPE_ID'"' >> $FILE_NAME - echo '' >> $FILE_NAME - echo '[provisioning.attestation]' >> $FILE_NAME - echo 'method = "symmetric_key"' >> $FILE_NAME - echo 'registration_id = "'$REGISTRATION_ID'"' >> $FILE_NAME - echo '' >> $FILE_NAME - echo 'symmetric_key = { value = "'$SYMMETRIC_KEY'" }' >> $FILE_NAME - echo '' >> $FILE_NAME - - apply_config_changes -} - -###################################### -# install_edge_runtime_cs +# install_edge_runtime # # - installs Azure IoT Edge Runtime 1.2 -# - generates the edge's configuration file from template and -# fills in the manual provisioning section from provided parameters # # ARGUMENTS: -# CONNECTION_STRING +# None # OUTPUTS: # Write output to stdout # RETURN: # updates the global variable OK_TO_CONTINUE in case of success to true. ###################################### -function install_edge_runtime_cs() { - if [[ $# != 1 || "$1" == "" ]]; +function install_edge_runtime() { + if [ "x$(command -v iotedge)" != "x" ]; then - log_error "IoTEdge Device Connection string is required" - exit ${EXIT_CODES[2]} + log_warn "Edge runtime is already available." + + if [[ "${parsed_cmds["FORCE_RUN"]}" == "" ]]; + then + read -p "Do you want to install again? [Y/n] " ans + if [ ${ans^} == 'Y' ]; + then + remove_packages + else + exit ${EXIT_CODES[9]} + fi + else + log_info "Force to run the installation!" + remove_packages + fi fi - if [ -x "$(command -v iotedge)" ]; + log_info "Installing edge runtime..." + + apt-get install -o Dpkg::Options::="--force-confdef" aziot-identity-service="${package_versions[0]}" aziot-edge="${package_versions[1]}" -y 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT & + long_running_command $! + exit_code=$? + if [[ $exit_code != 0 ]]; then - log_error "Edge runtime is already available." - exit ${EXIT_CODES[9]} + log_info "aziot-edged installation failed with exit code: %d" $exit_code + exit ${EXIT_CODES[10]} fi - - install_common - - # create config.toml - log_info "Create instance configuration 'config.toml'." - - local CONNECTION_STRING=$1 - - log_info "Set manual provisioning parameters." - - local FILE_NAME="/etc/aziot/config.toml" - - # create a config.toml - will replace existing - echo 'hostname = "'`hostname`'"' > $FILE_NAME - echo '' >> $FILE_NAME - echo '## Manual provisioning configuration' >> $FILE_NAME - echo '[provisioning]' >> $FILE_NAME - echo 'source = "manual"' >> $FILE_NAME - echo 'connection_string = "'$CONNECTION_STRING'"' >> $FILE_NAME - echo '' >> $FILE_NAME - - apply_config_changes + log_info "Installed edge runtime..." } diff --git a/src/install-hotfix.sh b/src/install-hotfix.sh new file mode 100755 index 0000000..1d81ced --- /dev/null +++ b/src/install-hotfix.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +#script to install hotfix for percept related functions + +###################################### +# install_defender_hotfix +# +# - Fix the system hang issue caused by Defender for IoT (defender-iot-micro-agent-edge) +# +# ARGUMENTS: +# None +# OUTPUTS: +# Write output to stdout +# RETURN: +# +###################################### + +function install_defender_hotfix() { + log_info "Installing defender hotfix ..." + dpkg -i ${VERSION_ID}/dmidecode_3.3-4_arm64.deb 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT & + long_running_command $! + exit_code=$? + if [[ $exit_code != 0 ]]; + then + log_info "dmidecode_3.3-4: installation failed with exit code: %d" $exit_code + exit ${EXIT_CODES[10]} + fi + log_info "Installed defender hotfix" +} diff --git a/src/install-percept-packages.sh b/src/install-percept-packages.sh new file mode 100755 index 0000000..9e79115 --- /dev/null +++ b/src/install-percept-packages.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash + +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +#script to install percept related packages + +###################################### +# install_osconfig +# +# - Install OSConfig +# +# ARGUMENTS: +# None +# OUTPUTS: +# Write output to stdout +# RETURN: +# +###################################### + +function install_osconfig() { + # OSConfig + log_info "Installing osconfig..." + apt-get install -o Dpkg::Options::="--force-confdef" osconfig="${package_versions[2]}" -y 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT & + long_running_command $! + exit_code=$? + if [[ $exit_code != 0 ]]; + then + log_info "osconfig installation failed with exit code: %d" $exit_code + exit ${EXIT_CODES[10]} + fi + log_info "Installed osconfig" +} + +###################################### +# install_defender +# +# - Install Defender for IoT (defender-iot-micro-agent-edge) +# +# ARGUMENTS: +# None +# OUTPUTS: +# Write output to stdout +# RETURN: +# +###################################### + +function install_defender() { + # Defender for IoT + log_info "Installing defender..." + apt-get install -o Dpkg::Options::="--force-confdef" defender-iot-micro-agent-edge="${package_versions[3]}" -y 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT & + long_running_command $! + exit_code=$? + if [[ $exit_code != 0 ]]; + then + log_info "defender installation failed with exit code: %d" $exit_code + exit ${EXIT_CODES[10]} + fi + log_info "Installed defender" +} + +###################################### +# configure_percept_services +# +# - Fix the warning and error messages from 'iotedge check' command +# +# ARGUMENTS: +# None +# OUTPUTS: +# Write output to stdout +# RETURN: +# updates the global variable OK_TO_CONTINUE in case of success to true. +###################################### + +function configure_percept_services() { + log_info "Set Docker default parameters" + local FILE_NAME="/etc/docker/daemon.json" + local existing_item="" + + if [ ! -f $FILE_NAME ]; + then + log_info "Create $FILE_NAME" + # create a docker daemon.json + echo '{' > $FILE_NAME + echo ' "dns": ["1.1.1.1", "8.8.8.8"],' >> $FILE_NAME + echo ' "log-driver": "json-file",' >> $FILE_NAME + echo ' "log-opts": {' >> $FILE_NAME + echo ' "max-size": "10m",' >> $FILE_NAME + echo ' "max-file": "3"' >> $FILE_NAME + echo ' }' >> $FILE_NAME + echo '}' >> $FILE_NAME + chmod 644 $FILE_NAME + else + # Log Driver & Options + existing_item="$(grep log-driver $FILE_NAME)" + if [ "x$existing_item" == "x" ]; + then + log_info "Add Log driver & options to $FILE_NAME" + sed -i '1 a\ + "log-driver": "json-file",\ + "log-opts": {\ + "max-size": "10m",\ + "max-file": "3"\ + },' $FILE_NAME + fi + + # DNS + existing_item="$(grep dns $FILE_NAME)" + if [ "x$existing_item" == "x" ]; + then + log_info "Add DNS to $FILE_NAME" + sed -i '1 a\ + "dns": ["1.1.1.1", "8.8.8.8"],' $FILE_NAME + fi + fi +} diff --git a/src/provision-and-configure.sh b/src/provision-and-configure.sh new file mode 100755 index 0000000..8fd31e9 --- /dev/null +++ b/src/provision-and-configure.sh @@ -0,0 +1,298 @@ +#!/usr/bin/env bash + +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +#script to provision & configure + +###################################### +# setup_product_info +# +# - Write OS Variant, Manufacturer & Product Name into /etc/product-info.toml +# - If the file exists AND the key name os_variant exists, do nothing +# - Add additional_info into /etc/aziot/config.toml.edge.template +# +# ARGUMENTS: +# +# OUTPUTS: +# Write output to stdout +# RETURN: +# +###################################### + +function setup_product_info() { + local PRODUCT_INFO_FILE="/etc/product-info.toml" + local os_varient="operating_system_variant" + local varient_mark="eai_installer" + local existing_item="" + + if [ ! -f $PRODUCT_INFO_FILE ]; + then + log_info "Create $PRODUCT_INFO_FILE" + touch $PRODUCT_INFO_FILE + chmod 644 $PRODUCT_INFO_FILE + + echo "${os_varient}=\"${varient_mark}\"" > $PRODUCT_INFO_FILE + echo "product_name=\"$(get_product_name)\"" >> $PRODUCT_INFO_FILE + echo "system_vendor=\"$(get_manufacturer)\"" >> $PRODUCT_INFO_FILE + else + # OS Varient + existing_item="$(grep $os_varient $PRODUCT_INFO_FILE)" + if [ "x$existing_item" == "x" ]; + then + log_info "Write ${os_varient} to $PRODUCT_INFO_FILE" + echo "${os_varient}=\"${varient_mark}\"" >> $PRODUCT_INFO_FILE + fi + # Product Name + existing_item="$(grep product_name $PRODUCT_INFO_FILE)" + if [ "x$existing_item" == "x" ]; + then + log_info "Write product_name to $PRODUCT_INFO_FILE" + echo "product_name=\"$(get_product_name)\"" >> $PRODUCT_INFO_FILE + fi + # Manufacturer + existing_item="$(grep system_vendor $PRODUCT_INFO_FILE)" + if [ "x$existing_item" == "x" ]; + then + log_info "Write system_vendor to $PRODUCT_INFO_FILE" + echo "system_vendor=\"$(get_manufacturer)\"" >> $PRODUCT_INFO_FILE + fi + fi + + local TEMPLATE_TOML_FILE="/etc/aziot/config.toml.edge.template" + if [ -f $TEMPLATE_TOML_FILE ]; + then + existing_item="$(grep additional_info $TEMPLATE_TOML_FILE)" + if [ "x$existing_item" == "x" ]; + then + log_info "Update $TEMPLATE_TOML_FILE" + sed -i '/parent_hostname/ a\ +\n\ +# ==============================================================================\ +# Additional information\ +# ==============================================================================\ +#\ +# Uncomment the next line to override the system information from /etc/os-release\ +#\ +additional_info = "file:///etc/product-info.toml"' $TEMPLATE_TOML_FILE + fi + fi +} + +###################################### +# stop_iotedge_service +# +# - Stop iotedge services before we do provisioning +# +# ARGUMENTS: +# +# OUTPUTS: +# Write output to stdout +# RETURN: +# +###################################### + +function stop_iotedge_service() +{ + local status=$(sudo iotedge system status | grep -i running) + + if [ "$status" != "" ]; then + log_info "Stop iotedge services ..." + iotedge system stop 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT & + long_running_command $! + fi +} + +###################################### +# setup_hostname +# +# - Get hostname from either given value, connnection string or DPS registration id. +# - Update device hostname +# - Remove existing containers with old hostname +# +# ARGUMENTS: +# HOSTNAME +# CONNECTION_STRING or REGISTRATION_ID +# OUTPUTS: +# Write output to stdout +# RETURN: +# updates the global variable OK_TO_CONTINUE in case of success to true. +###################################### + +function setup_hostname() { + if [[ $# == 2 && "$1" != "" && "$2" != "" ]]; + then + local NEW_HOSTNAME=$1 + # get hostname from connection string or DPS registration id + if [[ "$1" == "true" ]]; + then + NEW_HOSTNAME=$2 + if [[ "$2" != *"DeviceId="* ]]; + then + log_info "Assign DPS registration id (${NEW_HOSTNAME}) as hostname" + else + local DEVICE_ID=${NEW_HOSTNAME#*;DeviceId=} + NEW_HOSTNAME=${DEVICE_ID%;SharedAccessKey=*} + log_info "Assign Device ID (${NEW_HOSTNAME}) as hostname" + fi + else + log_info "New hostname: ${NEW_HOSTNAME}" + fi + + # update device's hostname + log_info "Update device hostname..." + local OLD_HOSTNAME=`hostname` + hostnamectl set-hostname $NEW_HOSTNAME 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT + sed -i "s/${OLD_HOSTNAME}/${NEW_HOSTNAME}/g" /etc/hosts 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT + sudo systemctl restart avahi-daemon.service 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT + + log_info "Device hostname is set completely" + + # remove the containers with old hostname + if [[ "x$(docker ps -aq -f name=edgeHub -f name=edgeAgent)" != "x" ]]; + then + log_info "Remove existing containers: edgeHub, edgeAgent" + docker rm -f $(docker ps -aq -f name=edgeHub -f name=edgeAgent) 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT + fi + fi +} + +###################################### +# dps_provisioning +# +# - generates the edge's configuration file from template and +# fills in the DPS provisioning section from provided parameters +# +# ARGUMENTS: +# SCOPE_ID +# REGISTRATION_ID +# SYMMETRIC_KEY +# OUTPUTS: +# Write output to stdout +# RETURN: +# updates the global variable OK_TO_CONTINUE in case of success to true. +###################################### + +function dps_provisioning() { + if [[ $# != 3 || "$1" == "" || "$2" == "" || "$3" == "" ]]; + then + log_error "Scope ID, Registration ID, and the Symmetric Key are required" + exit ${EXIT_CODES[2]} + fi + + # create config.toml + log_info "Create instance configuration 'config.toml'." + + local SCOPE_ID=$1 + local REGISTRATION_ID=$2 + local SYMMETRIC_KEY=$3 + + log_info "Set DPS provisioning parameters." + + local FILE_NAME="/etc/aziot/config.toml" + + # create a config.toml - will replace existing + echo 'hostname = "'`hostname`'"' > $FILE_NAME + echo 'additional_info = "file:///etc/product-info.toml"' >> $FILE_NAME + echo '' >> $FILE_NAME + echo '## DPS provisioning with symmetric key' >> $FILE_NAME + echo '[provisioning]' >> $FILE_NAME + echo 'source = "dps"' >> $FILE_NAME + echo '' >> $FILE_NAME + echo 'global_endpoint = "https://global.azure-devices-provisioning.net"' >> $FILE_NAME + echo 'id_scope = "'$SCOPE_ID'"' >> $FILE_NAME + echo '' >> $FILE_NAME + echo '[provisioning.attestation]' >> $FILE_NAME + echo 'method = "symmetric_key"' >> $FILE_NAME + echo 'registration_id = "'$REGISTRATION_ID'"' >> $FILE_NAME + echo '' >> $FILE_NAME + echo 'symmetric_key = { value = "'$SYMMETRIC_KEY'" }' >> $FILE_NAME + echo '' >> $FILE_NAME + + log_info "Apply settings - this will restart the edge" + iotedge config apply 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT + exit_code=$? + if [[ $exit_code == 0 ]]; + then + log_info "IotEdge has been configured successfully" + else + log_error "Cannot apply config! Please check ${BOLD}$STDERR_REDIRECT${DEFAULT} for details" + exit ${EXIT_CODES[2]} + fi +} + +###################################### +# cs_provisioning +# +# - get the connection string from provided parameters and +# run 'iotedge config' commands to apply the connection string +# +# ARGUMENTS: +# CONNECTION_STRING +# OUTPUTS: +# Write output to stdout +# RETURN: +# updates the global variable OK_TO_CONTINUE in case of success to true. +###################################### + +function cs_provisioning() { + if [[ $# != 1 || "$1" == "" ]]; + then + log_error "Connection string is required" + exit ${EXIT_CODES[2]} + fi + + if [[ "$1" != *"HostName"* || "$1" != *"DeviceId"* || "$1" != *"SharedAccessKey"* ]]; + then + log_error "Connection string is invalid! Make sure the connection string includes 'HostName', 'DeviceId' & 'SharedAccessKey' keywords or check if double quotes (\"\") are used as parameters!" + exit ${EXIT_CODES[2]} + fi + + log_info "Assign connection string to the config file" + iotedge config mp --force --connection-string $1 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT + + log_info "Write configurations to config.toml" + local FILE_NAME="/etc/aziot/config.toml" + sed -i "1 a hostname = \"`hostname`\"" $FILE_NAME + sed -i "2 a additional_info = \"file:///etc/product-info.toml\"" $FILE_NAME + + log_info "Apply settings - this will restart the edge" + iotedge config apply 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT + exit_code=$? + if [[ $exit_code == 0 ]]; + then + log_info "IotEdge has been configured successfully" + else + log_error "Cannot apply config! Please check ${BOLD}$STDERR_REDIRECT${DEFAULT} for details" + exit ${EXIT_CODES[2]} + fi +} + +###################################### +# reset_percept_services +# +# - restart docker and percept specific services +# +# ARGUMENTS: +# None +# OUTPUTS: +# Write output to stdout +# RETURN: +# +###################################### + +function reset_percept_services() { + log_info "Restart docker service ..." + sudo systemctl restart docker 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT + exit_code=$? + if [[ $exit_code == 0 ]]; + then + log_info "Docker has been configured successfully" + fi + + log_info "Restart osconfig service" + sudo systemctl restart osconfig.service + + log_info "Restart defender service" + sudo systemctl restart defender-iot-micro-agent.service +} diff --git a/src/read-config-file.sh b/src/read-config-file.sh new file mode 100755 index 0000000..9d3faab --- /dev/null +++ b/src/read-config-file.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash + +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +#script to read JSON format input file + +###################################### +# prepare_json +# +# - Check perl package for json query feature +# +# ARGUMENTS: +# +# OUTPUTS: +# Write output to stdout +# RETURN: +# +###################################### +function prepare_json() { + if [ "x$(command -v json_pp)" != "x" ]; + then + log_info "Perl JSON::PP module is available" + else + log_error "Please install 'perl' package for --input-file option by running '${YELLOW}sudo apt-get install perl -y${DEFAULT}'." + exit ${EXIT_CODES[6]} + fi +} + +###################################### +# file_parser +# +# - Parse configurations from the input json file +# +# ARGUMENTS: +# JSON file path +# OUTPUTS: +# Write output to stdout +# RETURN: +# +###################################### +declare -A parsed_cfgs +declare -a cfg_options=("{action}{do_install}" + "{action}{do_provisioning}" + "{action}{do_hotfix}") + +function file_parser() { + local perl_cmd='local $/;my $json=JSON::PP->new;print $json->encode( $json->decode()->' + local is_found=false + + if [ $# != 1 ]; + then + exit ${EXIT_CODES[2]} + else + input_file=$1 + if [ -f $input_file ]; + then + log_info "Read configurations from %s ..." $input_file + for key in ${!cfg_options[*]}; + do + cat $input_file | perl -MJSON::PP -e "${perl_cmd}${cfg_options[$key]} )" 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT + exit_code=$? + if [[ $exit_code == 0 ]]; + then + is_found=true + fi + + parsed_cfgs[${cfg_options[$key]}]=$(cat $input_file | perl -MJSON::PP -e "${perl_cmd}${cfg_options[$key]} )" 2>>$STDERR_REDIRECT) + log_info "\t${YELLOW}${cfg_options[$key]} = ${parsed_cfgs[${cfg_options[$key]}]}${DEFAULT}" + done + if [[ $is_found == false ]]; + then + log_error "Cannot find valid item! Please check the input file." + exit ${EXIT_CODES[2]} + fi + + # prompt to users for action + if [[ "${parsed_cmds["FORCE_RUN"]}" == "" ]]; + then + read -p "Is the configuration correct? [Y/n] " ans + if [ ${ans^} == 'Y' ]; + then + log_info "Processing the configuration ..." + else + exit ${EXIT_CODES[2]} + fi + else + log_info "Force to process the configuration ..." + fi + else + log_error "The config file '%s' does not exist!" $input_file + exit ${EXIT_CODES[2]} + fi + fi +} diff --git a/src/show-help-menu.sh b/src/show-help-menu.sh new file mode 100755 index 0000000..e82d822 --- /dev/null +++ b/src/show-help-menu.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +#script to show help menu + +###################################### +# show_help +# +# - Display HELP menu for options +# +# ARGUMENTS: +# None +# OUTPUTS: +# Write output to stdout +# RETURN: +# +###################################### + +function show_help() { + echo "" + echo "${BOLD}Usage: sudo ./azure-iot-edge-installer.sh [OPTION]...${DEFAULT}" + echo "" + echo "${BOLD}Basic:${DEFAULT}" + echo -e "\t-h, --help\t\t\t\t\tPrint this help" + echo -e "\t-f, --force\t\t\t\t\tRun installation immediately without prompt" + echo -e "\t-u, --upgrade\t\t\t\t\tInstall upgrades for the installed packages only and ignore new package installation" + echo "" + echo "${BOLD}Connection String Provisioning:${DEFAULT}" + echo -e "\t-c, --connection-string \tThe Azure IoT Edge Device Connection String" + echo -e "${MAGENTA}\tThe default provisioning method. For example," + echo -e "\t$ sudo ./azure-iot-edge-installer.sh -c \"\"" + echo -e "${DEFAULT}" + echo "${BOLD}DPS Provisioning:${DEFAULT}" + echo -e "\t-s, --scope-id \t\t\tThe Azure DPS ID Scope" + echo -e "\t-r, --registration-id \t\tThe Azure DPS enrollment Registration ID" + echo -e "\t-k, --symmetric-key \t\tThe Symmetric Key for the individual enrollment" + echo -e "${MAGENTA}\tThree arguments above are all neccessary for DPS provisioning. For example," + echo -e "\t$ sudo ./azure-iot-edge-installer.sh -s -r -k " + echo "${DEFAULT}" + echo "${BOLD}Advanced:${DEFAULT}" + echo -e "\t-hn, --hostname [HOSTNAME]\t\t\tSet hostname for both device & IoT Edge" + echo -e "${MAGENTA}\tIf no value is given, the hostname is automatically extracted from the connection string (DeviceID field)" + echo -e "\tor set as the DPS registration id. Otherwise, the given value would overwrite the automatic naming options.\n" + echo -e "\tPlease also notice that the hostname should comply with RFC 1035." + echo -e "\t - Hostname must be between 1 and 255 octets inclusive." + echo -e "\t - Each label in the hostname (component separated by \".\") must be between 1 and 63 octets inclusive." + echo -e "\t - Each label must start with an ASCII alphabet character (a-z, A-Z), end with an ASCII alphanumeric character (a-z, A-Z, 0-9), and must contain only ASCII alphanumeric character or hypens (a-z, A-Z, 0-9, \"-\")" + echo "${DEFAULT}" + echo -e "\t-i, --input-file \t\t\tRead the configurations from a JSON format input file" + echo -e "${MAGENTA}\tIt supports the 'action' field. Please refer to .json files in the 'config' folder." + echo -e "\tFor example, you can do provisioning only by this way: (make sure 'aziot-edge' is installed before running this)" + echo -e "\t$ sudo ./azure-iot-edge-installer.sh -i config/provision-only.json -c \"\"" + echo -e "\t- OR -" + echo -e "\t$ sudo ./azure-iot-edge-installer.sh -i config/provision-only.json -s -r -k " + echo "${DEFAULT}" + echo "${BOLD}Telemetry:${DEFAULT}" + echo -e "\t-nt, --telemetry-opt-out\t\t\tDisable usage telemetry feature" + echo -e "\t-cv, --correlation-vector\t\t\tCorrelation vector specific to the run\n" +} diff --git a/src/utils.sh b/src/utils.sh old mode 100644 new mode 100755 index 00b9d91..7d51a58 --- a/src/utils.sh +++ b/src/utils.sh @@ -160,7 +160,7 @@ function cmd_parser() { parsed_cmd[${flag_to_variable_dict[$key]}]="" done - local arg_pos=0 + local count=1 while [ $# -ne 0 ]; do if [[ $1 == -* ]]; @@ -174,12 +174,17 @@ function cmd_parser() { valid_argument=true if [[ $# == 1 || $2 == -* ]]; then - arg_pos=$(($arg_pos+1)) parsed_cmd[${flag_to_variable_dict[$key]}]=true else - arg_pos=$(($arg_pos+2)) - parsed_cmd[${flag_to_variable_dict[$key]}]=\${$arg_pos} + if [[ "$1" == "-c" || "$1" == "--connection-string" ]]; + then + count=$(($count+1)) + parsed_cmd[${flag_to_variable_dict[$key]}]=\${$count} + else + parsed_cmd[${flag_to_variable_dict[$key]}]=$2 + fi shift + count=$(($count+1)) fi break fi @@ -197,6 +202,7 @@ function cmd_parser() { fi shift + count=$(($count+1)) done # view content of entire dictionary @@ -361,8 +367,8 @@ function prepare_apt() { if [[ $? == 0 ]]; then log_info "apt function testing ... remove apt-utils" - apt-get remove apt-utils -y 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT & - long_running_command $! + echo "If no response for a while, press CTRL + C to exit and run '${YELLOW}sudo apt remove apt-utils${DEFAULT}' for details." + apt remove apt-utils -y 1>>$STDOUT_REDIRECT exit_code=$? if [[ $exit_code != 0 ]]; then @@ -372,8 +378,8 @@ function prepare_apt() { fi log_info "apt function testing ... install apt-utils" - apt-get install apt-utils -y 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT & - long_running_command $! + echo "If no response for a while, press CTRL + C to exit and run '${YELLOW}sudo apt-get install apt-utils${DEFAULT}' for details." + apt-get install apt-utils -y 1>>$STDOUT_REDIRECT exit_code=$? if [[ $exit_code != 0 ]]; then @@ -386,6 +392,78 @@ function prepare_apt() { fi } +###################################### +# get_manufacturer +# +# - Retrieved the Manufacturer info from SMBIOS +# +# ARGUMENTS: +# OUTPUTS: +# Write output to stdout +# RETURN: +# +###################################### + +function get_manufacturer() { + local manufacturer="" + manufacturer="$(sudo dmidecode -t system | grep Manufacturer | cut -d ':' -f 2)" + echo ${manufacturer:1} +} + +###################################### +# get_product_name +# +# - Retrieved the Product Name info from SMBIOS +# +# ARGUMENTS: +# OUTPUTS: +# Write output to stdout +# RETURN: +# +###################################### + +function get_product_name() { + local product_name="" + product_name="$(sudo dmidecode -t system | grep "Product Name" | cut -d ':' -f 2)" + echo ${product_name:1} +} + +export -f get_manufacturer get_product_name + +###################################### +# only_upgrade +# +# - Install upgrades for the installed packages only and skip installing new packages +# +# ARGUMENTS: +# OUTPUTS: +# Write output to stdout +# RETURN: +# +###################################### + +function only_upgrade() { + # update list + log_info "apt-get update ..." + apt-get update 2>>$STDERR_REDIRECT 1>>$STDOUT_REDIRECT & + long_running_command $! + exit_code=$? + if [[ $exit_code != 0 ]]; + then + log_error "apt-get update failed!" $exit_code + fi + + # only upgrade + log_info "apt-get --only-upgrade install for percept specific packages ..." + apt-get --only-upgrade install -y ${percept_packages[@]} + exit_code=$? + if [[ $exit_code != 0 ]]; + then + log_error "apt-get --only-upgrade install failed!" $exit_code + exit ${EXIT_CODES[6]} + fi +} + BG_PROCESS_ACTIVE=false BG_PROCESS_ID=-1 ###################################### @@ -411,7 +489,7 @@ function long_running_command() { do for next_symbol in '-' '\\' '|' '/'; do - echo -en "$next_symbol ${GREEN}Running ${DEFAULT}...\b\b\b\b\b\b\b\b\b\b\b\b\b\b" + echo -en "$next_symbol\b" sleep 0.15 local MYPS=$(ps -a | awk '/'$BG_PROCESS_ID'/ {print $1}') if [ "$MYPS" == "" ]; @@ -421,7 +499,7 @@ function long_running_command() { fi done done - echo -en " \b\b\b\b\b\b\b\b\b\b\b\b\b\b" + echo -en " \b" wait $BG_PROCESS_ID BG_PROCESS_ID=-1 fi @@ -497,26 +575,15 @@ function handle_exit() { if [[ "$LOCAL_E2E" == "1" ]]; then - iotedge check if [[ $e_code != 0 ]]; then echo errors-file ----------------------------- - echo '' cat $STDERR_REDIRECT - echo '' echo errors-file ----------------------------- fi echo stdout-file ----------------------------- - echo '' cat $STDOUT_REDIRECT - echo '' echo stdout-file ----------------------------- - - echo config-file ----------------------------- - echo '' - cat /etc/aziot/config.toml - echo '' - echo config-file ----------------------------- fi announce_my_log_file "All logs were appended to" $OUTPUT_FILE diff --git a/src/validate-post-install.sh b/src/validate-post-install.sh old mode 100644 new mode 100755 index 1f5f7ed..906a3e8 --- a/src/validate-post-install.sh +++ b/src/validate-post-install.sh @@ -3,30 +3,48 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. -###################################### -# validate-post-install.sh -# -# Utility function to check if the IoT Edgre Runtime local services are running -# ARGUMENTS: -# Service name -# "sudo iotedge system status" output -# OUTPUTS: -# Write output to stdout -# RETURN: -# 0 if service is running, 1 otherwise -###################################### - function is_service_running() { + local retry_max=5 local service_name=${1,,} - local iotedge_status=${2,,} + + for retry in $(seq 1 $retry_max) + do + + local status=$(sudo iotedge system status) + local iotedge_status=${status,,} service_status=$(awk '/'$service_name'/ {print $2}' <<< $iotedge_status) if [ "$service_status" != "running" ] && [ "$service_status" != "ready" ]; + then + if [ $retry == $retry_max ]; + then + log_error "'%s' is not running." $service_name + log_error "Run these commands to gather additional logs:" + log_error "sudo iotedge system logs" + log_error "sudo iotedge check" + return 1 + else + # Wait 3 seconds and retry + sleep 3 + fi + else + log_info "'%s' is running." $service_name + return 0 + fi + + done +} + +function is_percept_service_running() { + local service_name=${1,,} + + sudo systemctl is-active --quiet $service_name + exit_code=$? + if [[ $exit_code != 0 ]]; then log_error "'%s' is not running." $service_name log_error "Run these commands to gather additional logs:" - log_error "sudo iotedge system logs" - log_error "sudo iotedge check" + log_error "sudo systemctl status %s" $service_name return 1 fi @@ -34,10 +52,22 @@ function is_service_running() { return 0 } +###################################### +# validate-post-install +# +# Utility function to check if the IoT Edgre Runtime local services are running +# ARGUMENTS: +# Service name +# "sudo iotedge system status" output +# OUTPUTS: +# Write output to stdout +# RETURN: +# 0 if service is running, 1 otherwise +###################################### + function validate_post_install() { log_info "Post install validation starting." - local status=$(iotedge system status) - + declare -a iotedge_services=("aziot-edged" "aziot-identityd" "aziot-keyd" @@ -46,10 +76,41 @@ function validate_post_install() { for service_name in "${iotedge_services[@]}" do - is_service_running $service_name "$status" + is_service_running $service_name + done + + declare -a percept_services=("osconfig" + "defender-iot-micro-agent") + + for service_name in "${percept_services[@]}" + do + is_percept_service_running $service_name done log_info "Post install validation completed." } -export -f validate_post_install +###################################### +# show_package_version +# +# - Print the version of all installed packages +# +# ARGUMENTS: +# None +# OUTPUTS: +# Write output to stdout +# RETURN: +# updates the global variable OK_TO_CONTINUE in case of success to true. +###################################### + +function show_package_version() { + log_info "Installed package version:" + + for package_name in "${percept_packages[@]}" + do + package_version=$(apt-cache policy $package_name | grep Installed | cut -d ' ' -f 4) + log_info " %s: %s" $package_name $package_version + done +} + +export -f validate_post_install show_package_version diff --git a/src/validate-tier1-os.sh b/src/validate-tier1-os.sh old mode 100644 new mode 100755 index 25a6f62..2d78853 --- a/src/validate-tier1-os.sh +++ b/src/validate-tier1-os.sh @@ -30,7 +30,7 @@ function is_os_tier1() { ;; raspbian) - if [ "$VERSION_CODENAME" == "bullseye" ] || [ "$VERSION_CODENAME" == "stretch" ] || [ "$VERSION_ID" == "9" ] || [ "$VERSION_ID" == "11" ]; + if [ "$VERSION_CODENAME" == "stretch" ] || [ "$VERSION_ID" == "9" ]; then return 0 fi @@ -74,12 +74,7 @@ function get_platform() { ;; raspbian) - if [ "$VERSION_CODENAME" == "bullseye" ] || [ "$VERSION_ID" == "11" ]; - then - os_platform="$ID_LIKE/11" - else - os_platform="$ID_LIKE/stretch/multiarch" - fi + os_platform="$ID_LIKE/stretch/multiarch" ;; esac @@ -88,3 +83,28 @@ function get_platform() { export -f is_os_tier1 get_platform +###################################### +# is_aarch64 +# +# - Check if the platform architecture is aarch64 +# +# ARGUMENTS: +# +# OUTPUTS: +# Write output to stdout +# RETURN: +# 0 if the architecture is aarch64, 1 otherwise (x86_64) +###################################### + +function is_aarch64() { + local os_arch=$(uname -p) + + if [[ $os_arch == "aarch64" ]]; + then + return 0 + else + return 1 + fi +} + +export -f is_aarch64 diff --git a/tests/e2e-tests/test-devicestate.sh b/tests/e2e-tests/test-devicestate.sh deleted file mode 100644 index a657326..0000000 --- a/tests/e2e-tests/test-devicestate.sh +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -###################################### -# test-devicestate -# -# End to end test to validate that the azure-iot-edge-installer.sh -# succesfully gets the Central device to provisioned state -# ARGUMENTS: -# subscription - The Azure subscription where the Central app is created -# OUTPUTS: -# Write output to stdout -# RETURN: -# 0 if test succeeds, 1 otherwise -###################################### - -###################################### -# Clean up test resources -# ARGUMENTS: -# armToken - Azure Resource Manager token for itneracting with the Azure subscription -# apiToken - the API token used for interaction with Central app -# device_id - the ID of the newly created device -# token_id - the API token ID used for interaction with Central app -# rg - resource group name for central app -# centralapp_name - central app name -# OUTPUTS: -# Write output to stdout -# RETURN: -# Void -###################################### -function cleanup() { - echo Starting cleanup - - local armToken=$1 - local apiToken=$2 - local device_id=$3 - local token_id=$4 - local rg=$5 - local centralapp_name=$6 - - # Clean up device if it exists - local out=$(curl -X GET -H "Authorization:$apiToken" https://${centralapp_name}.azureiotcentral.com/api/preview/devices/${device_id}) - echo $out - local device_exists=$(jq -r '.id' <<< "$out") - if [ "$device_exists" == "$device_id" ]; - then - echo Device ${device_id} exists - echo Delete device ${device_id} - curl -X DELETE -H "Authorization:Bearer $armToken" https://${centralapp_name}.azureiotcentral.com/api/preview/devices/${device_id} - else - echo Device ${device_id} does not exist - fi; - - # Clean up API token if it exists - local out=$(curl -X GET -H "Authorization:$apiToken" https://${centralapp_name}.azureiotcentral.com/api/preview/apiTokens/${token_id}) - echo $out - local apiToken_exists=$(jq -r '.id' <<< "$out") - if [ "$apiToken_exists" == "$token_id" ]; - then - echo API token ${token_id} exists - echo Delete API token ${token_id} - curl -X DELETE -H "Authorization:Bearer $armToken" https://${centralapp_name}.azureiotcentral.com/api/preview/apiTokens/${token_id} - else - echo API token ${token_id} does not exist - fi; - - # Clean up central app - echo Clean up central app - az iot central app delete -g ${rg} -n ${centralapp_name} -y - - echo Completed cleanup -} - -# Azure IoT DDE team subscription -subscription=$1 - -# Create a random number to make sure create new resources per each run -let num=$RANDOM*$RANDOM -prefix=e2e -token_id="${prefix}testtoken${num}" -device_id="${prefix}testdevice${num}" -device_displayName=$device_id -device_template=dtmi:p7xmntslpen:vzbw2mcng -test_result=1 # fail by default -rg=PipelineResources-IoTEdgeConfig -centralapp_name=${prefix}test-iotc-inventory-app${num} - -# The Central app is stored in PipelineResources-IoTEdgeConfig resource group -echo Get access token to subscription "Azure IoT Edge Dev Tools - Test" -out=$(az account get-access-token --resource https://apps.azureiotcentral.com -s ${subscription}) -echo $out -armToken=$(jq -r '.accessToken' <<< "$out") - -# Create a central app -echo Create a central app -az iot central app create -g ${rg} -n ${centralapp_name} -s ${centralapp_name} --template iotc-inventory - -# Create API token -echo Create API token to interact with Central app -out=$(curl -X PUT -d '{"roles":[{"role":"ca310b8d-2f4a-44e0-a36e-957c202cd8d4"}]}' -H "Content-Type:application/json" -H "Authorization:Bearer $armToken" https://${centralapp_name}.azureiotcentral.com/api/preview/apiTokens/${token_id}); -echo $out -apiToken=$(jq -r '.token' <<< "$out") - -if [ "$apiToken" == "null" ]; -then - echo Failed to create API token. Exit. - exit $test_result; -fi; - -echo Create a new device -out=$(curl -X PUT -d '{"displayName":"'$device_displayName'","instanceOf":"'$device_template'","simulated":false,"approved":true}' -H "Content-Type: application/json" -H "Authorization:$apiToken" https://${centralapp_name}.azureiotcentral.com/api/preview/devices/${device_id}) -echo $out -devicestate_before=$(jq -r '.provisioned' <<< "$out") -echo New device state is provisioned=$devicestate_before - -if [ "$devicestate_before" != "false" ]; -then - echo "Error: New device must not be provisioned. Cleanup and exit." - cleanup "$armToken" "$apiToken" "$device_id" "$token_id" "$rg" "$centralapp_name" - exit $test_result -else - echo "Device is not provisioned as expected. Continue."; -fi; - -echo Get device credentials -creds=$(curl -X GET -H "Authorization:$apiToken" https://${centralapp_name}.azureiotcentral.com/api/preview/devices/${device_id}/credentials) -echo $creds -scope_id=$(jq -r '.idScope' <<< "$creds") -primary_key=$(jq -r '.symmetricKey.primaryKey' <<< "$creds") - -echo Run the Azure IoT Edge Installer -#wget -O azure-iot-edge-installer.sh https://github.com/Azure/iot-edge-config/releases/latest/download/azure-iot-edge-installer.sh \ -cd ./../../src -chmod u+x azure-iot-edge-installer.sh -sudo LOCAL_E2E=1 ./azure-iot-edge-installer.sh --telemetry-opt-out --scope-id "$scope_id" --registration-id "$device_id" --symmetric-key "$primary_key" -chmod u-x azure-iot-edge-installer.sh - -# give 2 mins for changes to propagate to central app -sleep 120 - -# device state should be provisioned after running the script -out=$(curl -X GET -H "Authorization:$apiToken" https://${centralapp_name}.azureiotcentral.com/api/preview/devices/${device_id}) -echo $out -devicestate_after=$(jq -r '.provisioned' <<< "$out") -echo After running azure-iot-edge-installer.sh, new device state is provisioned=$devicestate_after - -if [ "$devicestate_after" != "true" ]; -then - echo "Error: Device must be provisioned. Exit."; -else - echo "Device is provisioned as expected. Success."; - test_result=0 # success -fi; - -# Clean up -cleanup "$armToken" "$apiToken" "$device_id" "$token_id" "$rg" "$centralapp_name" - -exit $test_result diff --git a/tests/e2e-tests/test-edge-deployment.json b/tests/e2e-tests/test-edge-deployment.json deleted file mode 100644 index 2ab6246..0000000 --- a/tests/e2e-tests/test-edge-deployment.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "content": { - "modulesContent": { - "$edgeAgent": { - "properties.desired": { - "schemaVersion": "1.1", - "runtime": { - "type": "docker", - "settings": { - "minDockerVersion": "v1.25", - "loggingOptions": "", - "registryCredentials": {} - } - }, - "systemModules": { - "edgeAgent": { - "type": "docker", - "settings": { - "image": "mcr.microsoft.com/azureiotedge-agent:1.2", - "createOptions": "{}" - } - }, - "edgeHub": { - "type": "docker", - "status": "running", - "restartPolicy": "always", - "settings": { - "image": "mcr.microsoft.com/azureiotedge-hub:1.2", - "createOptions": "{\"HostConfig\":{\"PortBindings\":{\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}" - } - } - }, - "modules": { - "SimulatedTemperatureSensor": { - "version": "1.0", - "type": "docker", - "status": "running", - "restartPolicy": "always", - "settings": { - "image": "mcr.microsoft.com/azureiotedge-simulated-temperature-sensor:1.0", - "createOptions": "{}" - } - } - } - } - }, - "$edgeHub": { - "properties.desired": { - "schemaVersion": "1.1", - "routes": { - "upstream": "FROM /messages/* INTO $upstream" - }, - "storeAndForwardConfiguration": { - "timeToLiveSecs": 7200 - } - } - }, - "SimulatedTemperatureSensor": { - "properties.desired": { - "SendData": true, - "SendInterval": 5 - } - } - } - } -} \ No newline at end of file diff --git a/tests/e2e-tests/test-ihedgecs.sh b/tests/e2e-tests/test-ihedgecs.sh deleted file mode 100644 index ff15509..0000000 --- a/tests/e2e-tests/test-ihedgecs.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -###################################### -# test-ihedgecs -# -# End to end test to validate that the azure-iot-edge-installer.sh -# succesfully gets the Central device to provisioned state -# ARGUMENTS: -# subscription - The Azure subscription where the Central app is created -# OUTPUTS: -# Write output to stdout -# RETURN: -# 0 if test succeeds, 1 otherwise -###################################### - -# Azure IoT DDE team subscription -subscription=$1 - -# Create a random number to make sure create new resources per each run -let num=$RANDOM*$RANDOM -prefix=e2e -iothub_id="${prefix}-ih-${num}" -edge_device_id="${prefix}-testdevice-${num}" -device_displayName=$edge_device_id -rg_name=PipelineResources-IoTEdgeConfig - -az account set -s ${subscription} - -echo Create the test IoT Hub '${iothub_id}' for the run -az iot hub create --resource-group ${rg_name} --location westus2 --name ${iothub_id} --sku S2 - -echo Create the edge device '${edge_device_id}' for the run, edge enabled -az iot hub device-identity create -n ${iothub_id} -d ${edge_device_id} --ee - -echo Retrieve the connection string -out=$(az iot hub device-identity connection-string show -n ${iothub_id} -d ${edge_device_id}) -device_connection_string=$(jq -r '.connectionString' <<< "$out") - -echo Configure the edge device with a test deployment manifest -az iot edge set-modules --hub-name ${iothub_id} --device-id ${edge_device_id} --content ./test-edge-deployment.json - -echo Run the Azure IoT Edge Installer -#wget -O azure-iot-edge-installer.sh https://github.com/Azure/iot-edge-config/releases/latest/download/azure-iot-edge-installer.sh \ -cd ./../../src -chmod u+x azure-iot-edge-installer.sh -sudo LOCAL_E2E=1 ./azure-iot-edge-installer.sh --telemetry-opt-out --connection-string "${device_connection_string}" -chmod u-x azure-iot-edge-installer.sh - -# Give 2 mins for changes to propagate to central app -sleep 120 - -# Clean up - az iot hub delete --resource-group ${rg_name} --name ${iothub_id} \ No newline at end of file diff --git a/tests/e2e-tests/test-uninstall.sh b/tests/e2e-tests/test-uninstall.sh deleted file mode 100644 index a32d566..0000000 --- a/tests/e2e-tests/test-uninstall.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -###################################### -# test-uninstall -# -# clean up between e2-e runs -# ARGUMENTS: -# OUTPUTS: -# Write output to stdout -# RETURN: -# 0 -###################################### - -#Question - is 'sudo' really needed here? -#Answer - it doesn't hurt! -echo Uninstall Azure IoTEdge and its subs -sudo apt-get remove --purge --auto-remove aziot-edge -y - -echo Remove any dangling docker containers -sudo docker rm $(sudo docker ps -a -q) > /dev/null 2>&1 - -echo Remove all docker images -sudo docker rmi -f $(sudo docker images -aq) > /dev/null 2>&1 - -echo Remove moby-engine and its subs -sudo apt-get remove --purge --auto-remove moby-engine -y - -echo Remove log, output and error files -sudo rm -f /tmp/azure-iot-edge-installer*.* > /dev/null 2>&1 diff --git a/tests/perf_tests.sh b/tests/perf_tests.sh deleted file mode 100644 index 96d881c..0000000 --- a/tests/perf_tests.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -###################################### -# perf_tests -# -# runs performance tests -# ARGUMENTS: -# an integer - number of times to run each test -# OUTPUTS: -# RETURN: -# 0 on success, -1 otherwise -###################################### - - -subscription=$(az account show | awk '/"id/ { print substr($2,2,36) }') - -# for each test ... -echo ./track_duration.sh -c $1 -t ./e2e-tests/test-devicestate.sh $subscription -cd e2e-tests -../track_duration.sh -v -c $1 -t ./test-devicestate.sh $subscription -cd .. - -exit 0 \ No newline at end of file diff --git a/tests/requirements.txt b/tests/requirements.txt deleted file mode 100644 index 736000d..0000000 --- a/tests/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -azure.iot.device diff --git a/tests/send_one_message_to_iot_hub_device.py b/tests/send_one_message_to_iot_hub_device.py deleted file mode 100644 index 94305b2..0000000 --- a/tests/send_one_message_to_iot_hub_device.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -import argparse -import sys - - -from azure.iot.device import IoTHubDeviceClient - - -# prepare the command line arguments parser -parser = argparse.ArgumentParser() -parser.add_argument("connection_string") -parser.add_argument("message") - -# parse the arguments -arguments = parser.parse_args() - -client = IoTHubDeviceClient.create_from_connection_string(arguments.connection_string) -client.send_message(arguments.message) -print(arguments.message) - -client.shutdown() diff --git a/tests/test_utils.sh b/tests/test_utils.sh deleted file mode 100644 index 5685ee5..0000000 --- a/tests/test_utils.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -# -error_output() { - printf "%b\n" "${RED:-}Error: $1${DEFAULT:-}" >&2 -} - -output() { - printf "%b\n" "${BOLD:-}${DEFAULT:-} $1" >&2 -} - -verbose_output() { - if [ "$verbose" = true ]; - then - output "$1" - fi -} - -export -f output error_output verbose_output - -NR_PASSING=0 -NR_FAILING=0 -NR_TOTALS=0 -assert_eq() { - local expected=$1; shift - local actual=$1; shift - - NR_TOTALS=$(bc <<< $NR_TOTALS+1) - if [ "$expected" == "$actual" ]; - then - NR_PASSING=$(bc <<< $NR_PASSING+1) - else - NR_FAILING=$(bc <<< $NR_FAILING+1) - error_output "expected: $expected; actual: $actual" - fi -} - -assert_not_eq() { - local expected=$1; shift - local actual=$1; shift - - NR_TOTALS=$(bc <<< $NR_TOTALS+1) - if [ "$expected" != "$actual" ]; - then - NR_PASSING=$(bc <<< $NR_PASSING+1) - else - NR_FAILING=$(bc <<< $NR_FAILING+1) - error_output "expected: $expected; actual: $actual" - fi -} - -assert_file() { - local file_name=$1; shift - - NR_TOTALS=$(bc <<< $NR_TOTALS+1) - if [[ -f $file_name ]]; - then - NR_PASSING=$(bc <<< $NR_PASSING+1) - else - NR_FAILING=$(bc <<< $NR_FAILING+1) - error_output "please call log_init prior to running the tests." - exit -1 - fi -} - -show_test_totals() { - local BN=`basename $0` - - printf "\n" - printf "$BN: total tests %d; %d passing; %d failing" "$NR_TOTALS" $NR_PASSING $NR_FAILING - printf "\n\n" -} - -export -f assert_eq assert_not_eq assert_file show_test_totals \ No newline at end of file diff --git a/tests/track_duration.sh b/tests/track_duration.sh deleted file mode 100644 index 284d7c1..0000000 --- a/tests/track_duration.sh +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -###################################### -# track_duration -# -# compute duration of runs for a given command and report them as messages -# to a predefined device associated with a specific azure iot hub -# ARGUMENTS: -# v/verbose if set, generates verbose logs -# c/count specify the number of runs -# t/test sepcify which command to run. Must be the last parameter -# all arguments will be passed as is to the specified command -# OUTPUTS: -# sends duration reports to the cloud -# RETURN: -# 0 on success, -1 otherwise -###################################### - -# Stop script on NZEC -set -e - -# Exposing stream 3 as a pipe to standard output of the script itself -exec 3>&1 - -# bring in the library -MY_LOCATION=$(dirname $0) -source ${MY_LOCATION}/test_utils.sh - -# -verbose=false -count=1 -test_command="" -script_name="$(basename "$0")" -declare -a runs -while [ $# -ne 0 ] -do - name="$1" - case "$name" in - -v|--verbose|-[Vv]erbose) - verbose=true - ;; - -c|--count|-[Cc]ount) - shift - count=$1 - ;; - -t|--test|-[Tt]est) - shift - test_command="$@" - test_name="$1" - shift $(bc <<< $#-1) - ;; - -?|--?|-h|--help|-[Hh]elp) - echo "Usage: $script_name [OPTIONS] -t|--test TestToRun [TEST_OPTIONS]" - echo " $script_name -h|-?|--help" - echo "" - echo "$script_name is a simple command line interface for collecting test runs duration averages." - echo " --test option specifies which test to run, with arguments, and must appear as the last option." - echo "" - echo "Options:" - echo " --verbose,-Verbose Display diagnostics information." - echo " --count,-Count Specify number of runs." - echo " -?,--?,-h,--help,-Help Shows this help message" - echo "" - exit 0 - ;; - *) - error_output "Unknown argument \`$name\`" - exit 1 - esac - - shift -done - -if [ $count -lt 0 ]; -then - exit -1 -fi - -if [ "$test_command" == "" ]; -then - exit -2 -fi - -# -IH_CONN_STR=$(az iot hub device-identity connection-string show -n e2etest-iotc-hub -d e2etest_iotc_d | awk '/connection/ { print $2 }' | sed -e 's;";;g') - -time_stamp=`date '+%Y-%m-%d %H:%M:%S'` -os_name="`uname`" -os_kernel="`uname -r`" - -total=0.0 -verbose_output "" -for ((curr = 1; curr <= $count; curr++)) -do - start=`date +%s.%N` - command $test_command - end=`date +%s.%N` - - runs[$curr-1]=$(bc <<< $end-$start) - total=$(bc <<< $total+${runs[$curr-1]}) - verbose_output "run $curr took $(bc <<< $end-$start) seconds" - python3 ${MY_LOCATION}/send_one_message_to_iot_hub_device.py "$IH_CONN_STR" "{\"OSName\": \"$os_name\", \"Kernel\": \"$os_kernel\", \"TestName\": \"$test_name\", \"TimeStamp\": \"$time_stamp\", \"Duration\": ${runs[$iter]}}" -done - -verbose_output "" -verbose_output "average run time for '$test_command' is: $(echo "scale = 3; $total/$count" | bc) seconds" -verbose_output "----------------------------------------------------------------------------------------------\n" - -exit 0 \ No newline at end of file diff --git a/tests/unit-tests/test-cmd-parser.sh b/tests/unit-tests/test-cmd-parser.sh deleted file mode 100644 index c62a525..0000000 --- a/tests/unit-tests/test-cmd-parser.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -# import utils.sh -source ../../src/utils.sh - -# add flag:variable_name dictionary entries -add_option_args "VERBOSE_LOGGING" -v --verbose -add_option_args "SCOPE_ID" -s --scope-id -add_option_args "REGISTRATION_ID" -r --registration-id -add_option_args "SYMMETRIC_KEY" -k --symmetric-key -add_option_args "DEVICE_PROVISIONING" -dp -add_option_args "AZURE_CLOUD_ID" -ap -add_option_args "CONNECTION_STRING" -c --connection-string - -# unit test to test all illegal flags, output should be empty -test_illegal_flags() { - # parse sample input to parser - declare -A parsed_cmds="$(cmd_parser -illegal val -t anotherillegalval -z yetanotherillegalval)" - - # compare output, should be empty - if [ "${parsed_cmds[*]}" != "" ]; - then - echo "Failed to pass unit test 'test_illegal_flags' in test-cmd-parser.sh. Non-empty result: ${parsed_cmds[*]}" - fi -} - -test_all_legal_flags_cn() { - # parse sample input to parser - declare -A parsed_cmds="$(cmd_parser $@)" - - # compare output, should be 'x;y;z', true - if [[ "${parsed_cmds['CONNECTION_STRING']}" != "x;y;z" || "${parsed_cmds['VERBOSE_LOGGING']}" != true ]]; - then - echo "Failed to pass unit test 'test_all_legal_flags_cn' in test-cmd-parser.sh. Non-empty result: ${parsed_cmds[*]}" - fi -} - -test_all_legal_flags_dps() { - # parse sample input to parser - declare -A parsed_cmds="$(cmd_parser $@)" - - # compare output, should be 123456 - if [[ "${parsed_cmds['DEVICE_PROVISIONING']}" != "1" || "${parsed_cmds['AZURE_CLOUD_ID']}" != "5" || "${parsed_cmds['SCOPE_ID']}" != "2" || "${parsed_cmds['REGISTRATION_ID']}" != "4" || "${parsed_cmds['SYMMETRIC_KEY']}" != "3" || "${parsed_cmds['VERBOSE_LOGGING']}" != "6" ]]; - then - echo "Failed to pass unit test 'test_all_legal_flags_dps' in test-cmd-parser.sh. Non-empty result: ${parsed_cmds[*]}" - fi -} - -test_extra_arguments() { - # parse sample input to parser - declare -A parsed_cmds="$(cmd_parser illegalinput 0 -ap 4 -s 1 -r 3 more -extra -k 2)" - - # compare output, should be 1 2 3 4 - if [ "${parsed_cmds[*]}" != "" ]; - then - echo "Failed to pass unit test 'test_extra_arguments' in test-cmd-parser.sh" - fi -} - -# run all tests -test_illegal_flags -test_all_legal_flags_cn -c 'x;y;z' -v -test_all_legal_flags_dps -dp 1 -ap 5 -s 2 -r 4 -k 3 -v 6 -test_extra_arguments diff --git a/tests/unit-tests/test-logger.sh b/tests/unit-tests/test-logger.sh deleted file mode 100644 index 7eb92ff..0000000 --- a/tests/unit-tests/test-logger.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -exec 3>&1 - -# bring in the utils library -source ../../src/utils.sh -source ../test_utils.sh - -log_init -assert_file $OUTPUT_FILE - -WC_L=`wc -l "$OUTPUT_FILE"` -WC=${WC_L% *} -assert_eq 0 $WC - -log_error "%s %d %.3f" one 2 12.3042 -log_error "two three" -WC_L=`wc -l "$OUTPUT_FILE"` -WC=${WC_L% *} -assert_eq 2 $WC - -log_warn "%s %d %.3f" one 2 12.3042 -log_warn "two three" -WC_L=`wc -l "$OUTPUT_FILE"` -WC=${WC_L% *} -assert_eq 4 $WC - -log_info "%s %d %.3f" one 2 12.3042 -log_info "two three" -WC_L=`wc -l "$OUTPUT_FILE"` -WC=${WC_L% *} -assert_eq 6 $WC - -STRVAL1="One" -INTVAL1=45 -FLOATVAL1=2453.56890 -log_info "---------------------------------------------" -log_info "'%s' ;" "$STRVAL1" -log_info "%.2f" $FLOATVAL1 -WC_L=`wc -l "$OUTPUT_FILE"` -WC=${WC_L% *} -assert_eq 9 $WC - -show_test_totals -rm $OUTPUT_FILE \ No newline at end of file diff --git a/tests/unit-tests/test-telemetry-flag.sh b/tests/unit-tests/test-telemetry-flag.sh deleted file mode 100644 index bd83eac..0000000 --- a/tests/unit-tests/test-telemetry-flag.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -exec 3>&1 - -# bring in the utils library -source ../../src/utils.sh -source ../test_utils.sh - -function test_flag_on() { - set_opt_out_selection true - assert_eq $(get_opt_in_selection) false -} - -function test_flag_off() { - set_opt_out_selection false - assert_eq $(get_opt_in_selection) true -} - -test_flag_on -test_flag_off -show_test_totals diff --git a/tests/unit-tests/test-validate-post-install.sh b/tests/unit-tests/test-validate-post-install.sh deleted file mode 100644 index fcfd151..0000000 --- a/tests/unit-tests/test-validate-post-install.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -source ../../src/utils.sh -source ../../src/validate-post-install.sh -source ../test_utils.sh - -test_service_running() { - is_service_running "servicenameA" "servicenameA Running" - assert_eq 0 $? -} - -test_service_ready() { - is_service_running "servicenameA" "servicenameA Ready" - assert_eq 0 $? -} - -test_service_not_running() { - is_service_running "servicenameA" "servicenameA Failed" - assert_eq 1 $? -} - -test_service_missing() { - is_service_running "servicenameA" "servicenameB Running" - assert_eq 1 $? -} - -test_service_casesensitive() { - is_service_running "servicenameA" "servicenameA ruNNing" - assert_eq 0 $? -} - -test_service_casesensitive() { - is_service_running "servicenameA" "servicenameA ruNNing" - assert_eq 0 $? -} - -# run tests -test_service_running -test_service_ready -test_service_not_running -test_service_missing -test_service_casesensitive - -show_test_totals diff --git a/tests/unit-tests/test-validate-tier1-os.sh b/tests/unit-tests/test-validate-tier1-os.sh deleted file mode 100644 index ca9ef77..0000000 --- a/tests/unit-tests/test-validate-tier1-os.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -source ../../src/utils.sh -source ../../src/validate-tier1-os.sh -source ../test_utils.sh - -test_ubuntu1804() { - ID="ubuntu" - VERSION_ID="18.04" - is_os_tier1 "$ID" "$VERSION_ID" - assert_eq 0 $? -} - -test_ubuntu2004() { - ID="ubuntu" - VERSION_ID="20.04" - is_os_tier1 "$ID" "$VERSION_ID" - assert_eq 0 $? -} - -test_raspbian() { - ID="raspbian" - VERSION_ID="9" - is_os_tier1 "$ID" "$VERSION_ID" - assert_eq 0 $? -} - -test_raspbian11() { - ID="raspbian" - VERSION_ID="11" - is_os_tier1 "$ID" "$VERSION_ID" - assert_eq 0 $? -} - -test_tier2() { - ID="debian" - VERSION_ID="9" - is_os_tier1 "$ID" "$VERSION_ID" - assert_eq 1 $? -} -test_tier2_11() { - ID="debian" - VERSION_ID="11" - is_os_tier1 "$ID" "$VERSION_ID" - assert_eq 1 $? -} - -# run tests -test_ubuntu1804 -test_ubuntu2004 -test_raspbian -test_raspbian11 -test_tier2 -test_tier2_11 - -show_test_totals diff --git a/vsts_ci/azure-pipelines-e2e.yml b/vsts_ci/azure-pipelines-e2e.yml deleted file mode 100644 index b181497..0000000 --- a/vsts_ci/azure-pipelines-e2e.yml +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -# Starter pipeline -# Start with a minimal pipeline that you can customize to build and deploy your code. -# Add steps that build, run tests, deploy, and more: -# https://aka.ms/yaml - -trigger: -- main - -stages: -- stage: E2ETest - displayName: E2E Tests - jobs: - - job: LinuxE2ETests - pool: - name: IoT-Devices-E2E - steps: - - template: continuous-e2e-setup.yml - - template: continuous-e2e-uninstalledge.yml - - template: continuous-e2e.yml - dependsOn: [] - condition: succeeded() - - - job: RaspberryPiE2ETests - pool: - name: Raspberry-Pi - steps: - - template: continuous-e2e-setup.yml - - template: continuous-e2e-uninstalledge.yml - - template: continuous-e2e.yml - dependsOn: [] - condition: succeeded() - - - job: Ubuntu1804E2ETests - pool: - vmImage: ubuntu-18.04 - steps: - - template: continuous-e2e-setup.yml - - template: continuous-e2e.yml - dependsOn: [] - condition: succeeded() - - - job: Ubuntu2004E2ETests - pool: - vmImage: ubuntu-20.04 - steps: - - template: continuous-e2e-setup.yml - - template: continuous-e2e.yml - dependsOn: [] - condition: succeeded() - diff --git a/vsts_ci/azure-pipelines-perf.yml b/vsts_ci/azure-pipelines-perf.yml deleted file mode 100644 index 9f9f8c6..0000000 --- a/vsts_ci/azure-pipelines-perf.yml +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -# Starter pipeline -# Start with a minimal pipeline that you can customize to build and deploy your code. -# Add steps that build, run tests, deploy, and more: -# https://aka.ms/yaml - -trigger: -- main - -stages: -- stage: PERFTests - displayName: Performance Tests - jobs: - - job: LinuxE2ETests - pool: - name: IoT-Devices-E2E - steps: - - template: continuous-e2e-setup.yml - - template: continuous-e2e-uninstalledge.yml - - template: continuous-perf.yml - dependsOn: [] - condition: succeeded() - - - job: RaspberryPiPerfTests - pool: - name: Raspberry-Pi - steps: - - template: continuous-e2e-setup.yml - - template: continuous-e2e-uninstalledge.yml - - template: continuous-perf.yml - dependsOn: [] - condition: succeeded() - - - job: Ubuntu1804PerfTests - pool: - vmImage: ubuntu-18.04 - steps: - - template: continuous-e2e-setup.yml - - template: continuous-perf.yml - dependsOn: [] - condition: succeeded() - - - job: Ubuntu2004PerfTests - pool: - vmImage: ubuntu-20.04 - steps: - - template: continuous-e2e-setup.yml - - template: continuous-perf.yml - dependsOn: [] - condition: succeeded() \ No newline at end of file diff --git a/vsts_ci/azure-pipelines.yml b/vsts_ci/azure-pipelines.yml deleted file mode 100644 index 7dd30cf..0000000 --- a/vsts_ci/azure-pipelines.yml +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -# Starter pipeline -# Start with a minimal pipeline that you can customize to build and deploy your code. -# Add steps that build, run tests, deploy, and more: -# https://aka.ms/yaml - -trigger: -- main - -stages: -- stage: UnitTest - displayName: Unit Tests - jobs: - - job: Linux1804UnitTests - pool: - vmImage: ubuntu-18.04 - steps: - - template: linux/continuous-linux.yml - - - job: Linux2004UnitTests - pool: - vmImage: ubuntu-20.04 - steps: - - template: linux/continuous-linux.yml - - - job: RaspberryPiUnitTests - pool: - vmImage: ubuntu-latest - steps: - - template: raspi/continuous-raspi.yml - - - job: GithubRelease - pool: - vmImage: ubuntu-18.04 - dependsOn: - - Linux1804UnitTests - - Linux2004UnitTests - - RaspberryPiUnitTests - condition: and(succeeded('Linux1804UnitTests'), succeeded('Linux2004UnitTests'), succeeded('RaspberryPiUnitTests')) - steps: - - script: | - mkdir dest - cp src/*.sh dest/ - displayName: Create dest/ directory - - task: GitHubRelease@1 - displayName: 'GitHub release (create) RC' - inputs: - gitHubConnection: 'github.com_cindydeng1998' - tagPattern: '^v?[0-9]+\.[0-9]+\.[0-9]+-rc[0-9]+$' - assets: 'dest/*.sh' - isDraft: true - - task: GitHubRelease@1 - displayName: 'GitHub release (create)' - inputs: - gitHubConnection: 'github.com_cindydeng1998' - tagPattern: '^v?[0-9]+\.[0-9]+\.[0-9]+$' - assets: 'dest/*.sh' - isDraft: true - - task: ComponentGovernanceComponentDetection@0 - inputs: - scanType: 'Register' - verbosity: 'Verbose' - alertWarningLevel: 'High' \ No newline at end of file diff --git a/vsts_ci/continuous-e2e-setup.yml b/vsts_ci/continuous-e2e-setup.yml deleted file mode 100644 index f43b53d..0000000 --- a/vsts_ci/continuous-e2e-setup.yml +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -steps: -- script: | - apt-get update -y - sudo apt-get install jq - displayName: 'Install jq' -- task: AzureCLI@2 - inputs: - azureSubscription: 'Azure IoT Edge Dev Tools - Test' - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - az config set extension.use_dynamic_install=yes_without_prompt - az upgrade - az extension add --name azure-iot - az --version - az account set -s $(AzureSubscriptionId) - displayName: 'Set Azure resources' \ No newline at end of file diff --git a/vsts_ci/continuous-e2e-uninstalledge.yml b/vsts_ci/continuous-e2e-uninstalledge.yml deleted file mode 100644 index d870c62..0000000 --- a/vsts_ci/continuous-e2e-uninstalledge.yml +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -steps: -- task: AzureCLI@2 - inputs: - azureSubscription: 'Azure IoT Edge Dev Tools - Test' - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - sudo apt-get remove --purge --auto-remove aziot-edge -y - sudo docker rm $(sudo docker ps -a -q) > /dev/null 2>&1 - sudo docker rmi -f $(sudo docker images -aq) > /dev/null 2>&1 - sudo apt-get remove --purge --auto-remove moby-engine -y - sudo rm -f /tmp/azure-iot-edge-installer*.* > /dev/null 2>&1 - displayName: 'Uninstall iotedge package from previous run' diff --git a/vsts_ci/continuous-e2e.yml b/vsts_ci/continuous-e2e.yml deleted file mode 100644 index 7befbfd..0000000 --- a/vsts_ci/continuous-e2e.yml +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -steps: -- task: AzureCLI@2 - inputs: - azureSubscription: 'Azure IoT Edge Dev Tools - Test' - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - cd tests/e2e-tests - chmod u+x test-devicestate.sh - ./test-devicestate.sh $(AzureSubscriptionId) - chmod u+x test-uninstall.sh - ./test-uninstall.sh - chmod u+x test-ihedgecs.sh - ./test-ihedgecs.sh $(AzureSubscriptionId) - displayName: 'Run All E2E Tests' diff --git a/vsts_ci/continuous-perf.yml b/vsts_ci/continuous-perf.yml deleted file mode 100644 index b9e5454..0000000 --- a/vsts_ci/continuous-perf.yml +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -steps: -- task: UsePythonVersion@0 - displayName: "Use Python 3.8" - inputs: - versionSpec: 3.8 - -- task: AzureCLI@2 - displayName: 'Run All Performance Tests' - inputs: - azureSubscription: 'Azure IoT Edge Dev Tools - Test' - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - cd tests - python3 --version - pip3 --version - pip3 install -r requirements.txt - chmod +x ./track_duration.sh - chmod +x ./perf_tests.sh - chmod +x ./e2e-tests/test-devicestate.sh - az config set extension.use_dynamic_install=yes_without_prompt - az extension add --name azure-iot - az --version - az account set -s $(AzureSubscriptionId) - ./perf_tests.sh $(NumberOfRuns) \ No newline at end of file diff --git a/vsts_ci/linux/continuous-linux.yml b/vsts_ci/linux/continuous-linux.yml deleted file mode 100644 index f3c0997..0000000 --- a/vsts_ci/linux/continuous-linux.yml +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -steps: -- script: echo Hello Linux! - displayName: 'Echo Hello Linux' - -- script: | - cd tests/unit-tests - chmod +x ./*.sh - ./test-validate-post-install.sh - ./test-validate-tier1-os.sh - ./test-cmd-parser.sh - ./test-logger.sh - ./test-telemetry-flag.sh - displayName: 'Run All Linux Unit Tests' diff --git a/vsts_ci/raspi/continuous-raspi.yml b/vsts_ci/raspi/continuous-raspi.yml deleted file mode 100644 index 501c44a..0000000 --- a/vsts_ci/raspi/continuous-raspi.yml +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -steps: -- script: echo Hello Raspi! - displayName: 'Echo Hello Raspi!' - -- script: | - cd tests/unit-tests - chmod +x ./*.sh - ./test-validate-post-install.sh - ./test-validate-tier1-os.sh - ./test-cmd-parser.sh - ./test-logger.sh - ./test-telemetry-flag.sh - displayName: 'Run All Raspberry Pi Unit Tests'