diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4ed89b3..2204bac 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,7 @@ jobs: name: Build EDC for RasPi with the devcontainer runs-on: ubuntu-24.04 env: - SENSCORD_VER: '0.1.33' + SENSCORD_VER: '0.1.34' steps: - name: Checkout uses: actions/checkout@v4 diff --git a/docs/how_to_use_ota_sample.md b/docs/how_to_use_ota_sample.md index 662b947..a54b065 100644 --- a/docs/how_to_use_ota_sample.md +++ b/docs/how_to_use_ota_sample.md @@ -25,6 +25,7 @@ The expected configuration format is: { "PRIVATE_deploy_firmware": { "req_info": {"req_id": "hogefugapiyo123"}, + "version": "1.0.0", "targets": [ { "component": 1, @@ -41,17 +42,25 @@ The expected configuration format is: **Configuration Parameters:** +**At `PRIVATE_deploy_firmware` level:** +* **req_info**: Request information object + - **req_id**: Unique identifier for this configuration request +* **version**: Optional package version identifier + - For Raspberry Pi EDC, this value is echoed back in the state response as-is + - If omitted, the field will not appear in the state response + +**In `targets` array:** * **component**: Integer value `1` (fixed) - Indicates the target of OTA is system firmware * **chip**: String value `main_chip` (fixed) - Represents the system firmware running on the main application processor -* **version**: Empty string (fixed) or omitted - OTA specification always updates to the latest EDC version -* **package_url**: Empty string (fixed) or omitted - System image download is handled automatically -* **hash**: Empty string (fixed) or omitted - Hash verification is handled automatically -* **size**: Integer value `0` (fixed) or omitted - Size is handled automatically +* **version**: Ignored if specified - OTA specification always updates to the latest EDC version +* **package_url**: Ignored if specified - System image download is handled automatically +* **hash**: Ignored if specified - Hash verification is handled automatically +* **size**: Ignored if specified - Size is handled automatically > **Important:** > For the OTA specification, only `component` and `chip` are required with fixed values as shown above. -> The `version`, `package_url`, `hash`, and `size` parameters can be omitted. If specified, they must be -> empty strings or `0`, otherwise the configuration will be treated as an error. +> The `version`, `package_url`, `hash`, and `size` parameters can be omitted. If specified, their values +> will be ignored, and the OTA process will proceed normally. **Minimal Configuration Example:** @@ -92,6 +101,7 @@ The device returns the following state format: { "PRIVATE_deploy_firmware": { "req_info": {"req_id": "hogefugapiyo123"}, + "version": "1.0.0", "targets": [ { "component": 1, @@ -103,22 +113,35 @@ The device returns the following state format: "progress": 100, "process_state": "done" } - ] - }, - "res_info": { - "res_id": "hogefugapiyo123", - "code": 0, - "detail_msg": "ok" + ], + "res_info": { + "res_id": "hogefugapiyo123", + "code": 0, + "detail_msg": "ok" + } } } ``` **State Response Parameters:** -**req_info:** -- Returned as-is from the configuration - -**targets:** +**At `PRIVATE_deploy_firmware` level:** +* **version**: + - For Raspberry Pi EDC: Echoes back the value from the configuration if it was specified + - If not specified in the configuration, this field will not appear in the state response + - This represents the package version identifier +* **req_info**: + - Returned as-is from the configuration +* **res_info**: + - **res_id**: Carries forward the `req_info.req_id` (or the latest value for spontaneous state reports) + - **code**: + - On success: `0` + - On failure: `13` + - **detail_msg**: + - On success: `ok` + - On failure: `internal` + +**In `targets` array:** - **component**: Fixed value `1` - **chip**: Fixed value `main_chip` - **package_url**: Empty string @@ -134,15 +157,6 @@ The device returns the following state format: - On success: `done` - On failure: `failed` -**res_info:** -- **res_id**: Carries forward the `req_info.req_id` (or the latest value for spontaneous state reports) -- **code**: - - On success: `0` - - On failure: `13` -- **detail_msg**: - - On success: `ok` - - On failure: `internal` - ### Additional Info State In addition to the `PRIVATE_deploy_firmware` state, the device also reports version information as a separate independent topic called `additional_info`: @@ -324,7 +338,31 @@ cd aitrios-edge-device-core > All commands in this section should be executed on the edge device (Raspberry Pi). > In this guide, we use `~/workspace` as the working directory. Replace it with your preferred path if needed. -### Step 3: Remove Previous Installations (If Any) +### Step 3: Set Up GitHub Authentication + +Since the aitrios-edge-device-core repository is private, you need to set up GitHub authentication +for the OTA update script to download the latest releases. + +Create a token file with your GitHub Personal Access Token: + +```bash +# On the edge device: Create configuration directory +sudo mkdir -p /etc/edge-device-core + +# Create token file (replace with your actual token) +echo "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" | sudo tee /etc/edge-device-core/github-token > /dev/null + +# Secure the token file (readable only by root) +sudo chmod 600 /etc/edge-device-core/github-token +``` + +> **Important:** +> - Replace `ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` with your actual GitHub Personal Access Token. +> - The token must have `repo` scope to access private repositories. +> - You can create a Personal Access Token at: https://github.com/settings/tokens +> - Keep your token secure and never share it publicly. + +### Step 4: Remove Previous Installations (If Any) On the edge device, if you have previously installed EDC or senscord packages using `apt`, remove them first to avoid conflicts with the OTA deployment structure. @@ -341,7 +379,7 @@ sudo rm -rf /opt/senscord > **Note:** > Skip this step if this is your first installation. -### Step 4: Set Up the OTA Update Script +### Step 5: Set Up the OTA Update Script On the edge device, copy the OTA update script to the system location and make it executable. @@ -357,7 +395,7 @@ sudo rm -fr /opt/senscord sudo rm -fr /opt/edc ``` -### Step 5: Install EDC and Senscord Using OTA Script +### Step 6: Install EDC and Senscord Using OTA Script On the edge device, run the OTA update script to download and install the latest versions of EDC and senscord. This will also create the initial blue-green deployment structure. @@ -374,7 +412,49 @@ sudo /sbin/edc_system_update.sh > - Creates the blue-green deployment structure at `/opt/edcA` and `/opt/edcB` > - Sets up symbolic links at `/opt/edc` and `/opt/senscord` -### Step 6: Configure the Systemd Service +### Step 7 (Optional): Replace with Test Binary + +> **Note:** +> This step is **optional** and should only be performed if you want to test OTA update functionality +> with a test binary. If you are using the production release for normal operations, skip this step +> and proceed directly to Step 8. + +If you have obtained a test binary and want to test the OTA update functionality, you can replace +the EDC binary and version file with test versions. + +```bash +# On the edge device: Navigate to the directory where you downloaded the test binary +cd ~/Downloads + +# Create a directory for extracting the .deb package +mkdir extract_dir + +# Extract the test .deb package (replace the filename with your actual test package) +dpkg-deb -x edge-device-core-*_arm64.deb extract_dir/ + +# Replace the EDC binary with the test binary +sudo cp ~/Downloads/extract_dir/usr/bin/edge_device_core /opt/edc/bin/edge_device_core + +# Set a test version number (e.g., 0.0.0) to simulate an older version +echo "Version: 0.0.0" | sudo tee /opt/edc/version_edc.txt > /dev/null +``` + +> **What this does:** +> - Extracts the test EDC binary from the .deb package +> - Replaces the current EDC binary with the test version +> - Sets the version to `0.0.0` so that the OTA update will detect it as an older version +> and perform an actual update when triggered + +After performing this step, you can test the OTA update functionality by triggering an update +through the console, which should update from version `0.0.0` to the latest release version. + +> **Important:** +> If you performed Step 7, make sure to return to the aitrios-edge-device-core repository directory before proceeding to Step 8: +> ```bash +> cd ~/workspace/aitrios-edge-device-core +> ``` + +### Step 8: Configure the Systemd Service On the edge device, deploy the systemd service file to enable automatic startup and service management. @@ -386,7 +466,7 @@ sudo systemctl stop edge-device-core.service sudo cp samples/ota/edge-device-core.service /etc/systemd/system/ ``` -### Step 7: Create Database and Configuration Directory +### Step 9: Create Database and Configuration Directory On the edge device, create the directory for EDC's database and configuration files. @@ -401,7 +481,7 @@ sudo cp script/update_psm_db.py /var/lib/edge-device-core/ export EDGE_DEVICE_CORE_DB_PATH=/var/lib/edge-device-core/db.sqlite3 ``` -### Step 8: Set Up Device Certificates +### Step 10: Set Up Device Certificates On the edge device, copy your device certificates to the system location. @@ -428,7 +508,7 @@ sudo cp ../*_cert.pem /etc/evp/ sudo cp ../*_key.pem /etc/evp/ ``` -### Step 9: Configure MQTT and Platform Parameters +### Step 11: Configure MQTT and Platform Parameters On the edge device, set the MQTT and platform parameters in the database. @@ -450,7 +530,7 @@ sudo python3 /var/lib/edge-device-core/update_psm_db.py --key PlStorageDataEvpIo sudo python3 /var/lib/edge-device-core/update_psm_db.py --key PlStorageDataEvpTls --value 0 --db-file "${EDGE_DEVICE_CORE_DB_PATH}" ``` -### Step 10: Configure Root Certificate +### Step 12: Configure Root Certificate On the edge device, set the root certificate for TLS verification. @@ -461,7 +541,7 @@ sudo python3 /var/lib/edge-device-core/update_psm_db.py --key PlStorageDataPkiRo sudo python3 /var/lib/edge-device-core/update_psm_db.py --key PlStorageDataPkiRootCertsHash --value "$(sha256sum "${ROOT_CA_PATH}" | cut -d' ' -f1)" --db-file ${EDGE_DEVICE_CORE_DB_PATH} ``` -### Step 11: Create Required Directories +### Step 13: Create Required Directories On the edge device, create additional directories required for EDC operation. @@ -470,7 +550,7 @@ On the edge device, create additional directories required for EDC operation. sudo mkdir -p /evp_data/modules ``` -### Step 12: Set Up udev Rules +### Step 14: Set Up udev Rules On the edge device, configure udev rules for I2C device access. @@ -482,7 +562,7 @@ sudo cp udev/60-edc.rules /etc/udev/rules.d/ sudo udevadm trigger --subsystem-match=i2c ``` -### Step 13: Start the EDC Service +### Step 15: Start the EDC Service On the edge device, now that everything is configured, start the EDC service. @@ -497,7 +577,7 @@ sudo systemctl start edge-device-core.service sudo systemctl enable edge-device-core.service ``` -### Step 14: Verify the Service is Running +### Step 16: Verify the Service is Running On the edge device, check the service status and logs to ensure EDC is running correctly. @@ -526,7 +606,7 @@ system_app_main.c ... [INF] agent connected to hub # Successfu - If you see `MQTT_ERROR_RECONNECT_FAILED`: This indicates that edge-device-core is unable to connect to the MQTT broker. Check your MQTT broker configuration and network connectivity. - If you see `agent connected to hub`: This indicates that edge-device-core is successfully connected to the MQTT broker and ready for operation. -### Step 15: Stop the EDC Service (Optional) +### Step 17: Stop the EDC Service (Optional) On the edge device, if you need to stop the EDC service for any reason: @@ -540,7 +620,7 @@ sudo systemctl stop edge-device-core.service **Issue: Service started before database configuration (PS Mode activation)** If you accidentally start the EDC service before completing the database configuration -(before Step 9), the service will start in PS mode and set the `QRModeStateFlag` in +(before Step 11), the service will start in PS mode and set the `QRModeStateFlag` in the database to `0x77777777` (2004318071). **Symptoms:** @@ -559,8 +639,8 @@ the database to `0x77777777` (2004318071). sudo rm -f /var/lib/edge-device-core/db.sqlite3 ``` -3. Reconfigure the database by repeating Step 9 (Configure MQTT and Platform Parameters) - and Step 10 (Configure Root Certificate) +3. Reconfigure the database by repeating Step 11 (Configure MQTT and Platform Parameters) + and Step 12 (Configure Root Certificate) **Issue: MODULE_DIR creation error** @@ -571,7 +651,7 @@ evp_agent: No such file or directory: Failed to create MODULE_DIR /evp_data/modu **Solution:** -Create the required directory (this is Step 11 of the setup): +Create the required directory (this is Step 13 of the setup): ```bash sudo mkdir -p /evp_data/modules ``` @@ -581,6 +661,35 @@ Then restart the EDC service: sudo systemctl restart edge-device-core.service ``` +**Issue: GitHub Authentication Failure** + +If the OTA update script fails to download the latest releases from GitHub, it may be due to +authentication issues with the GitHub Personal Access Token. + +**Symptoms:** +- OTA update script fails with authentication errors +- Unable to download EDC or senscord packages from GitHub releases + +**Solution:** + +Verify the GitHub token is properly configured: + +```bash +# Verify token file exists and has content +sudo cat /etc/edge-device-core/github-token + +# Check file permissions (should be -rw------- 1 root root) +ls -la /etc/edge-device-core/github-token + +# Test GitHub API access with token +TOKEN=$(sudo cat /etc/edge-device-core/github-token) +curl -H "Authorization: Bearer $TOKEN" \ + -H "Accept: application/vnd.github+json" \ + https://api.github.com/repos/SonySemiconductorSolutions/aitrios-edge-device-core/releases/latest | jq -r '.tag_name' +``` + +If the token test fails, recreate the token file with a valid GitHub Personal Access Token (see Step 3). + --- ## SCS (Console) Operations @@ -598,7 +707,24 @@ Before proceeding with console operations, ensure you have completed the First, register your edge device with the AITRIOS Cloud Console. Follow the device registration procedures provided in the AITRIOS documentation. -### Step 2: Import the OTA GENERIC Package +### Step 2: Verify Device State (additional_info) + +After registering your device, verify that the device is reporting its state correctly, +including version information. + +1. Navigate to **Console V2** → **Devices** +2. Select your device from the list +3. Click the **State** tab + +You will see the device state information including `additional_info`: + +![Additional Info State](images/additional_info.png) + +> **Note:** +> The information displayed in `additional_info` is implementation-dependent and may vary +> depending on the device firmware and configuration. + +### Step 3: Import the OTA GENERIC Package Import the OTA package for GENERIC devices into the console. @@ -611,7 +737,7 @@ Upon successful import, you will see a confirmation screen like this: ![Import Success](images/scs_import_success.png) -### Step 3: Execute Deployment from the UI +### Step 4: Execute Deployment from the UI Now you can deploy the OTA update to your device. @@ -646,7 +772,7 @@ If there are many packages listed, you can filter by **Target Device Type: GENER This will initiate the OTA update process on your device. -### Step 4: Verify the Results +### Step 5: Verify the Results You can verify the update status in multiple ways: @@ -678,7 +804,7 @@ developer tools (for Microsoft Edge): ![Deployment Success - Network View](images/deploy_success_3.png) -### Step 5: Reboot the Device +### Step 6: Reboot the Device After a successful OTA update, you must reboot the device to apply the changes. diff --git a/docs/images/additional_info.png b/docs/images/additional_info.png new file mode 100644 index 0000000..0ca10d6 Binary files /dev/null and b/docs/images/additional_info.png differ diff --git a/docs/images/deploy_success_3.png b/docs/images/deploy_success_3.png index 6f020c1..27945c6 100644 Binary files a/docs/images/deploy_success_3.png and b/docs/images/deploy_success_3.png differ diff --git a/meson.build b/meson.build index 8110662..788a131 100644 --- a/meson.build +++ b/meson.build @@ -5,7 +5,7 @@ project( 'edge device core', 'c', 'cpp', - version : '0.3.10', + version : '0.4.0', ) cc = meson.get_compiler('c') if meson.is_cross_build() diff --git a/samples/ota/README.md b/samples/ota/README.md index a32db7b..7a7fe08 100644 --- a/samples/ota/README.md +++ b/samples/ota/README.md @@ -21,7 +21,24 @@ The update system implements a blue-green deployment strategy where: ## Installation -### 1. Run the Update Script to Install the Latest EDC +### 1. Set Up GitHub Authentication + +Create a token file with your GitHub Personal Access Token: + +```bash +# Create configuration directory +sudo mkdir -p /etc/edge-device-core + +# Create token file (replace with your actual token) +echo "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" | sudo tee /etc/edge-device-core/github-token > /dev/null + +# Secure the token file (readable only by root) +sudo chmod 600 /etc/edge-device-core/github-token +``` + +**Note**: Obtain a GitHub Personal Access Token with `repo` scope from GitHub Settings > Developer settings > Personal access tokens. + +### 2. Run the Update Script to Install the Latest EDC ```bash # Copy the script to a system location @@ -34,7 +51,7 @@ sudo chmod +x /sbin/edc_system_update.sh sudo /sbin/edc_system_update.sh ``` -### 2. Deploy the Updated Service File +### 3. Deploy the Updated Service File ```bash # Stop the current service if it exists @@ -57,6 +74,9 @@ sudo systemctl enable edge-device-core.service ## Usage ### Basic Usage of Installation Script + +**Note**: Ensure GitHub authentication is configured (see Installation section). + ```bash # Perform a standard update sudo edc_system_update.sh @@ -80,21 +100,30 @@ sudo edc_system_update.sh --force - Fetches latest `edge-device-core` binary and `libparameter_storage_manager.so` from GitHub releases - Downloads latest `senscord-edc-rpi-*_arm64.deb` package -2. **OS Update Phase** (optional): +2. **Version Check Phase**: + - Extracts version from downloaded package metadata + - Compares with current version from `/opt/edc/version_edc.txt` + - Skips update if already on the same version (unless `--force` is used) + - Version files are created atomically during installation + +3. **OS Update Phase** (optional): - Updates Raspberry Pi OS packages using apt (can be skipped with `--skip-os`) - Performs `apt update` and `apt upgrade` operations -3. **Deployment Detection**: +4. **Deployment Detection**: - Detects current active deployment (`/opt/edcA` or `/opt/edcB`) - Selects alternate directory for new installation -4. **Installation Phase**: +5. **Installation Phase**: - Creates directory structure: `bin/`, `lib/` - Extracts and installs packages to target directory - Senscord content is extracted directly to deployment root + - Creates version files: + - `/opt/edcX/version_edc.txt` (format: `Version: X.Y.Z`) + - `/opt/edcX/opt/senscord/version_senscord.txt` (format: `Version: X.Y.Z`) - Validates installation integrity -5. **Activation Phase**: +6. **Activation Phase**: - Updates both `/opt/edc` and `/opt/senscord` symbolic links atomically - Points to new deployment after successful installation (provides rollback protection) @@ -109,15 +138,19 @@ sudo edc_system_update.sh --force │ │ └── edge-device-core │ ├── lib/ │ │ └── libparameter_storage_manager.so +│ ├── version_edc.txt # EDC version file │ └── opt/ # (from senscord deb package) │ └── senscord/ +│ └── version_senscord.txt # Senscord version file └── edcB/ # Green deployment ├── bin/ │ └── edge-device-core ├── lib/ │ └── libparameter_storage_manager.so + ├── version_edc.txt # EDC version file └── opt/ # (from senscord deb package) └── senscord/ + └── version_senscord.txt # Senscord version file ``` ## Service Configuration @@ -153,6 +186,7 @@ Environment="PATH=/opt/edc/opt/senscord/bin:/bin:/usr/bin:/usr/local/bin" - **Privileges**: Root access required - **Disk Space**: Minimum 1GB free space in `/opt/` - **Network**: Internet connectivity for GitHub downloads +- **Authentication**: GitHub Personal Access Token with `repo` scope stored in `/etc/edge-device-core/github-token` ### Required Utilities - `curl` - For downloading packages @@ -173,6 +207,14 @@ sudo apt install -y curl jq ## Safety Features +### Version Control +- **Automatic version detection**: Extracts version from package metadata +- **Update skipping**: Avoids redundant updates when already on latest version +- **Force update option**: `--force` flag bypasses version check for reinstallation +- **Version files**: Stores version information in each deployment for tracking + - Format: `Version: X.Y.Z` (one line, with "Version: " prefix) + - Locations: `/opt/edc/version_edc.txt` and `/opt/edc/opt/senscord/version_senscord.txt` + ### Rollback Protection - Installation to alternate directory ensures current deployment remains intact - Both symbolic links (`/opt/edc` and `/opt/senscord`) only updated after successful installation and validation @@ -194,13 +236,25 @@ sudo apt install -y curl jq ### Common Issues +#### Authentication Issues +```bash +# Verify token file exists and has content +sudo cat /etc/edge-device-core/github-token + +# Check file permissions (should be -rw------- 1 root root) +ls -la /etc/edge-device-core/github-token + +# Test GitHub API access with token +TOKEN=$(sudo cat /etc/edge-device-core/github-token) +curl -H "Authorization: Bearer $TOKEN" \ + -H "Accept: application/vnd.github+json" \ + https://api.github.com/repos/SonySemiconductorSolutions/aitrios-edge-device-core/releases/latest | jq -r '.tag_name' +``` + #### Download Failures ```bash # Check internet connectivity ping -c 4 api.github.com - -# Check GitHub API access -curl -s https://api.github.com/repos/aitrios/aitrios-edge-device-core/releases/latest ``` #### Permission Issues diff --git a/samples/ota/edc_system_update.sh b/samples/ota/edc_system_update.sh index d63ccf4..6424279 100755 --- a/samples/ota/edc_system_update.sh +++ b/samples/ota/edc_system_update.sh @@ -20,14 +20,34 @@ readonly SENSCORD_SYMLINK="/opt/senscord" readonly TEMP_DIR="/tmp/edc_update_$$" # GitHub repositories -readonly CORE_REPO="aitrios/aitrios-edge-device-core" -readonly SENSOR_REPO="aitrios/aitrios-edge-device-sensor" +readonly CORE_REPO="SonySemiconductorSolutions/aitrios-edge-device-core" +readonly SENSOR_REPO="SonySemiconductorSolutions/aitrios-edge-device-core-sensor" + +# GitHub authentication (required for private repositories) +readonly TOKEN_FILE="/etc/edge-device-core/github-token" + +# Load GitHub token from file +if [[ -f "$TOKEN_FILE" ]]; then + GITHUB_TOKEN=$(cat "$TOKEN_FILE" 2>/dev/null | tr -d '[:space:]') +else + GITHUB_TOKEN="" +fi + +readonly GITHUB_TOKEN # Downloaded files CORE_PACKAGE="" SENSOR_PACKAGE="" CORE_BINARY="" +# Version information +CORE_VERSION="" +SENSOR_VERSION="" + +# Command-line options +FORCE_UPDATE=false +SKIP_OS_UPDATE=false + # Color codes for output readonly RED='\033[0;31m' readonly GREEN='\033[0;32m' @@ -107,6 +127,14 @@ check_requirements() { error_exit "Insufficient disk space in /opt (need at least 1GB free)" fi + # GitHub token check (REQUIRED for private repositories) + if [[ -z "$GITHUB_TOKEN" ]]; then + error_exit "GitHub token not found. Please create $TOKEN_FILE with your GitHub personal access token." + else + log_debug "GitHub token loaded from file: $TOKEN_FILE" + log_debug "GitHub token length: ${#GITHUB_TOKEN}" + fi + log_info "System requirements check passed" } @@ -117,7 +145,10 @@ get_latest_release() { # Don't log here to avoid mixing with JSON output - if ! release_info=$(curl -s "https://api.github.com/repos/${repo}/releases/latest"); then + if ! release_info=$(curl -s \ + -H "Authorization: Bearer ${GITHUB_TOKEN}" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/${repo}/releases/latest"); then log_error "Failed to fetch release information for ${repo}" return 1 fi @@ -147,7 +178,10 @@ download_file() { log_info "Downloading $(basename "$output_file")..." - if ! curl -L -o "$output_file" "$url"; then + if ! curl -L \ + -H "Authorization: Bearer ${GITHUB_TOKEN}" \ + -H "Accept: application/octet-stream" \ + -o "$output_file" "$url"; then error_exit "Failed to download $url" fi @@ -194,7 +228,8 @@ download_core_packages() { fi # Extract URL for the .deb package (contains both binary and library) - download_url_binary=$(jq -r '.assets[] | select(.name | test("edge-device-core-[0-9.]+.*_arm64\\.deb$")) | .browser_download_url' "$temp_json" 2>/dev/null || echo "") + # Use API URL instead of browser_download_url for private repositories + download_url_binary=$(jq -r '.assets[] | select(.name | test("edge-device-core-[0-9.]+.*_arm64\\.deb$")) | .url' "$temp_json" 2>/dev/null || echo "") # Debug: show all available assets log_debug "All available assets:" @@ -234,7 +269,8 @@ download_sensor_package() { local temp_json="${TEMP_DIR}/sensor_release_info.json" echo "$release_info" > "$temp_json" - download_url=$(jq -r '.assets[] | select(.name | test("senscord-edc-rpi-[0-9.]+.*_arm64\\.deb$")) | .browser_download_url' "$temp_json" 2>/dev/null || echo "") + # Use API URL instead of browser_download_url for private repositories + download_url=$(jq -r '.assets[] | select(.name | test("senscord-edc-rpi-[0-9.]+.*_arm64\\.deb$")) | .url' "$temp_json" 2>/dev/null || echo "") if [[ -z "$download_url" ]]; then log_debug "Available assets:" @@ -310,6 +346,7 @@ install_core_packages() { local target_dir="$1" log_info "Installing core packages to $target_dir..." + log_info "Installing edge-device-core version: $CORE_VERSION" # Extract core .deb package and find the binary and library local extract_dir="${TEMP_DIR}/core_extract" @@ -355,6 +392,13 @@ install_core_packages() { cp "$library_path" "$target_dir/lib/libparameter_storage_manager.so" chmod 644 "$target_dir/lib/libparameter_storage_manager.so" + # Create version file in /tmp then move to target + local temp_version_file="/tmp/version_edc_$$.txt" + echo "Version: $CORE_VERSION" > "$temp_version_file" + chmod 644 "$temp_version_file" + mv "$temp_version_file" "$target_dir/version_edc.txt" + log_info "Created EDC version file: $target_dir/version_edc.txt (Version: $CORE_VERSION)" + log_debug "Core packages installed successfully" } @@ -364,11 +408,31 @@ install_sensor_package() { log_info "Installing sensor package to $target_dir..." + # Extract version from .deb package + SENSOR_VERSION=$(dpkg-deb -I "$SENSOR_PACKAGE" | grep '^ Version:' | awk '{print $2}') + if [[ -z "$SENSOR_VERSION" ]]; then + error_exit "Could not extract version from sensor .deb package" + fi + log_info "Installing senscord version: $SENSOR_VERSION" + # Extract .deb package directly to target directory (not to senscord subdirectory) if ! dpkg-deb -x "$SENSOR_PACKAGE" "$target_dir"; then error_exit "Failed to extract sensor package" fi + # Create version file in senscord directory + local senscord_dir="$target_dir/opt/senscord" + if [[ ! -d "$senscord_dir" ]]; then + error_exit "Senscord directory not found after extraction: $senscord_dir" + fi + + # Create version file in /tmp then move to target + local temp_version_file="/tmp/version_senscord_$$.txt" + echo "Version: $SENSOR_VERSION" > "$temp_version_file" + chmod 644 "$temp_version_file" + mv "$temp_version_file" "$senscord_dir/version_senscord.txt" + log_info "Created senscord version file: $senscord_dir/version_senscord.txt (Version: $SENSOR_VERSION)" + log_debug "Sensor package installed successfully (content extracted directly to deployment root)" } @@ -460,6 +524,34 @@ perform_update() { download_core_packages download_sensor_package + # Extract version from downloaded package + CORE_VERSION=$(dpkg-deb -I "$CORE_PACKAGE" | grep '^ Version:' | awk '{print $2}') + if [[ -z "$CORE_VERSION" ]]; then + error_exit "Could not extract version from downloaded .deb package" + fi + log_info "Downloaded edge-device-core version: $CORE_VERSION" + + # Check if update is needed (unless --force is specified) + if [[ "$FORCE_UPDATE" == true ]]; then + log_info "Force update enabled, skipping version check" + else + local current_version_file="$EDC_SYMLINK/version_edc.txt" + if [[ -f "$current_version_file" ]]; then + local current_version + current_version=$(grep '^Version:' "$current_version_file" | awk '{print $2}') + + if [[ -n "$current_version" && "$current_version" == "$CORE_VERSION" ]]; then + log_info "Already on latest version: $current_version" + log_info "Skipping update. Use --force to update anyway." + return 0 + fi + + log_info "Current version: ${current_version:-unknown}, Latest version: $CORE_VERSION" + else + log_info "No current version file found, proceeding with installation" + fi + fi + # Determine deployment strategy local current_deployment target_deployment current_deployment=$(detect_current_deployment) @@ -548,9 +640,6 @@ os_update() { # Main function main() { - local force=false - local skip_os=false - # Parse command line arguments while [[ $# -gt 0 ]]; do case $1 in @@ -563,11 +652,11 @@ main() { exit 0 ;; --force) - force=true + FORCE_UPDATE=true shift ;; --skip-os) - skip_os=true + SKIP_OS_UPDATE=true shift ;; *) @@ -589,7 +678,7 @@ main() { check_requirements # Execute OS update (unless skipped) - if [[ "$skip_os" != true ]]; then + if [[ "$SKIP_OS_UPDATE" != true ]]; then if ! os_update; then log_warn "OS update failed, but continuing with edge-device-core update" fi diff --git a/src/app b/src/app index 6134ad0..8fc1857 160000 --- a/src/app +++ b/src/app @@ -1 +1 @@ -Subproject commit 6134ad09b06f72686cd5879a4002ed825f298706 +Subproject commit 8fc18579be666c7a5c429bd23a4dce6c3db39c72 diff --git a/src/sensor b/src/sensor index 2bdd738..18de856 160000 --- a/src/sensor +++ b/src/sensor @@ -1 +1 @@ -Subproject commit 2bdd7382fdecd2107867f4257950d2e67e75c545 +Subproject commit 18de85639abadcc5131ac4aa02ac88fba71b192f