Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(plugins): add Matter plugin support #4491

Merged
merged 27 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
311052a
Add Matter plugin
MonicaisHer Dec 11, 2023
76fa675
Add comments for Matter SDK building related commands
MonicaisHer Dec 12, 2023
815b68e
Use plugin name as a prefix for plugin-specific keywords
MonicaisHer Dec 14, 2023
a0fcab5
Replace storage paths in Matter SDK
MonicaisHer Dec 14, 2023
872a234
Format and uncomment
MonicaisHer Dec 14, 2023
90740f3
Update plugin keywords names, move bootstrap script after path replac…
MonicaisHer Dec 15, 2023
18b3a68
Enhance formatting and remove redundant copy command
MonicaisHer Jan 2, 2024
da14ed1
Add unit and spread tests for Matter plugin
MonicaisHer Jan 25, 2024
61adb5e
Merge branch 'main' into IENG-860
MonicaisHer Jan 26, 2024
7c484e2
Remove ZAP build, export `PATH` only
MonicaisHer Feb 12, 2024
d34cc01
Remove ZAP plugin-specific keyword
MonicaisHer Feb 12, 2024
9f5c229
Prepend PATH difference to existing PATH
MonicaisHer Feb 15, 2024
76d8ce7
Fix format, source matter-sdk-env.sh file in matter lighting snap
MonicaisHer Feb 15, 2024
f529f0f
Merge branch 'main' into IENG-860
MonicaisHer Feb 15, 2024
1cb674d
Use shell parameter expansion
MonicaisHer Feb 15, 2024
eca52bd
Remove extra separator
MonicaisHer Feb 16, 2024
12e1e6a
Combine multiple statements into one for better readability
MonicaisHer Feb 23, 2024
0e415a2
Remove obsolete if statement
MonicaisHer Feb 23, 2024
ffcd7c6
Stage plugin env script, and flag plugin as experimental
MonicaisHer Mar 7, 2024
a9c3920
Revert "Stage plugin env script, and flag plugin as experimental"
MonicaisHer Mar 7, 2024
f1c69bb
Flag plugin as experimental
MonicaisHer Mar 7, 2024
b7b4663
Stage plugin env script
MonicaisHer Mar 7, 2024
cefacd7
Check experimental matter plugin in lifecycle test
MonicaisHer Mar 11, 2024
94da1bc
Merge branch 'main' into IENG-860
MonicaisHer Mar 11, 2024
7916db5
Merge branch 'main' into IENG-860
syu-w Mar 20, 2024
76df76b
Remove extra line
MonicaisHer Mar 21, 2024
849dbfe
chore(merge): 'main' into 'IENG-860'
mr-cal Apr 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion snapcraft/parts/lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
import argparse


_EXPERIMENTAL_PLUGINS = ["kernel"]
_EXPERIMENTAL_PLUGINS = ["kernel", "matter-sdk"]


def run(command_name: str, parsed_args: "argparse.Namespace") -> None:
Expand Down
2 changes: 2 additions & 0 deletions snapcraft/parts/plugins/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@
from .conda_plugin import CondaPlugin
from .flutter_plugin import FlutterPlugin
from .kernel_plugin import KernelPlugin
from .matter_sdk_plugin import MatterSdkPlugin
from .python_plugin import PythonPlugin
from .register import get_plugins, register

__all__ = [
"ColconPlugin",
"CondaPlugin",
"FlutterPlugin",
"MatterSdkPlugin",
"KernelPlugin",
"PythonPlugin",
"get_plugins",
Expand Down
178 changes: 178 additions & 0 deletions snapcraft/parts/plugins/matter_sdk_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright 2023 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# 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 <http://www.gnu.org/licenses/>.

"""The matter SDK plugin."""
import os
from typing import Any, Dict, List, Set, cast

from craft_parts import infos, plugins
from overrides import overrides

# The repository where the matter SDK resides.
MATTER_SDK_REPO = "https://github.com/project-chip/connectedhomeip"


class MatterSdkPluginProperties(plugins.PluginProperties, plugins.PluginModel):
"""The part properties used by the matter SDK plugin."""

matter_sdk_version: str

@classmethod
@overrides
def unmarshal(cls, data: Dict[str, Any]) -> "MatterSdkPluginProperties":
"""Populate class attributes from the part specification.

:param data: A dictionary containing part properties.

:return: The populated plugin properties data object.

:raise pydantic.ValidationError: If validation fails.
"""
plugin_data = plugins.extract_plugin_properties(
data,
plugin_name="matter-sdk",
required=["matter_sdk_version"],
)
return cls(**plugin_data)


class MatterSdkPlugin(plugins.Plugin):
"""A plugin for matter SDK project.

This plugin uses the common plugin keywords.
For more information check the 'plugins' topic.

Additionally, this plugin uses the following plugin-specific keywords:
- matter-sdk-version
(str, no default)
The matter SDK version to use for the build.
"""

properties_class = MatterSdkPluginProperties

def __init__(
self,
*,
properties: plugins.PluginProperties,
part_info: infos.PartInfo,
) -> None:
super().__init__(properties=properties, part_info=part_info)

self.matter_sdk_dir = part_info.part_build_dir
self.snap_arch = os.getenv("SNAP_ARCH")

@overrides
def get_pull_commands(self) -> List[str]:
options = cast(MatterSdkPluginProperties, self._options)
commands = []

# Clone Matter SDK repository
commands.extend(
[
" git init",
f" git remote add origin {MATTER_SDK_REPO}",
f" git fetch --depth 1 origin {options.matter_sdk_version}",
" git checkout FETCH_HEAD",
]
)

# Checkout submodules for Linux platform
commands.extend(["scripts/checkout_submodules.py --shallow --platform linux"])

return commands

@overrides
def get_build_packages(self) -> Set[str]:
return {
"clang",
"cmake",
"generate-ninja",
"git",
"libavahi-client-dev",
"libcairo2-dev",
"libdbus-1-dev",
"libgirepository1.0-dev",
"libglib2.0-dev",
"libreadline-dev",
"libssl-dev",
"ninja-build",
"pkg-config",
"python3-dev",
"python3-pip",
"python3-venv",
"unzip",
"wget",
}

@overrides
def get_build_environment(self) -> Dict[str, str]:
return {}

@overrides
def get_build_snaps(self) -> Set[str]:
return set()

@overrides
def get_build_commands(self) -> List[str]:
commands = []

# The project writes its data to /tmp which isn't persisted.

# Setting TMPDIR env var when running the app isn't sufficient as
# chip_[config,counter,factory,kvs].ini still get written under /tmp.
# The chip-tool currently has no way of overriding the default paths to
# storage and security config files.

# Snap does not allow bind mounting a persistent directory on /tmp,
# so we need to replace it in the source with another path, e.g. /mnt.
# The consumer snap needs to bind mount a persisted directory within
# the confined snap space on /mnt.

# Replace storage paths
commands.extend(
[
r"sed -i 's/\/tmp/\/mnt/g' src/platform/Linux/CHIPLinuxStorage.h",
r"sed -i 's/\/tmp/\/mnt/g' src/platform/Linux/CHIPPlatformConfig.h",
]
)

# Store the initial value of PATH before executing the bootstrap script
commands.extend(["OLD_PATH=$PATH"])

# Bootstrapping script for building Matter SDK with minimal "build" requirements
# and setting up the environment.
commands.extend(
["set +u && source scripts/setup/bootstrap.sh --platform build && set -u"]
)

commands.extend(["echo 'Built Matter SDK'"])

# Compare the difference between the original PATH and the modified PATH
commands.extend(
[
'MATTER_SDK_PATHS="${PATH%$OLD_PATH}"',
]
)

# Prepend the Matter SDK related PATH to the beginning of the PATH environment variable,
# and save it to the staging area as matter-sdk-env.sh file.
commands.extend(
[
'echo "export PATH=$MATTER_SDK_PATHS\\$PATH" >> $CRAFT_STAGE/matter-sdk-env.sh',
]
)

return commands
2 changes: 2 additions & 0 deletions snapcraft/parts/plugins/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from .conda_plugin import CondaPlugin
from .flutter_plugin import FlutterPlugin
from .kernel_plugin import KernelPlugin
from .matter_sdk_plugin import MatterSdkPlugin
from .python_plugin import PythonPlugin


Expand All @@ -36,6 +37,7 @@ def get_plugins(core22: bool) -> dict[str, PluginType]:
"conda": CondaPlugin,
"flutter": FlutterPlugin,
"python": PythonPlugin,
"matter-sdk": MatterSdkPlugin,
}

if core22:
Expand Down
48 changes: 48 additions & 0 deletions tests/spread/plugins/craft-parts/matter-sdk/snapcraft.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: matter-lighting
summary: Matter plugin test
description: An lighting application to test the matter plugin.
version: "1.0"

base: core22

grade: stable
build-base: core22
confinement: strict

layout:
/mnt:
bind: $SNAP_COMMON/mnt

apps:
matter-lighting:
daemon: simple
command: bin/lighting-app
install-mode: disable
plugs:
- network
- network-bind
- bluez
- avahi-control

parts:
matter-sdk:
plugin: matter-sdk
matter-sdk-version: "1536ca20c5917578ca40ce509400e97b52751788" # use this commit with ptpython version fix; needs to be updated once matter sdk have a stable release

lighting:
plugin: nil
after: [matter-sdk]
override-build: |
# Source the Matter SDK environment variables
source $CRAFT_STAGE/matter-sdk-env.sh

# Build the lighting app for snapcraft spread testing purposes
cd ../../matter-sdk/build/examples/lighting-app/linux
gn gen out/build
ninja -C out/build

ldd out/build/chip-lighting-app

mkdir -p $CRAFT_PART_INSTALL/bin
cp out/build/chip-lighting-app $CRAFT_PART_INSTALL/bin/lighting-app

50 changes: 50 additions & 0 deletions tests/spread/plugins/craft-parts/matter-sdk/task.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
summary: Craft Parts matter SDK plugin test
manual: true
kill-timeout: 180m

systems:
- ubuntu-22.04-64

prepare: |
#shellcheck source=tests/spread/tools/snapcraft-yaml.sh
. "$TOOLS_DIR/snapcraft-yaml.sh"
set_base "$SNAP/snap/snapcraft.yaml"

restore: |
cd "$SNAP"
snapcraft clean
rm -f ./*.snap

#shellcheck source=tests/spread/tools/snapcraft-yaml.sh
. "$TOOLS_DIR/snapcraft-yaml.sh"
restore_yaml "snap/snapcraft.yaml"

execute: |
cd "$SNAP"

# Build and install the snap
snapcraft
snap install "${SNAP}*.snap" --dangerous

start_time=$(date +"%Y-%m-%d %H:%M:%S")
snap start matter-lighting

# Check if storage path replacement from /tmp to SNAP_COMMON/mnt works
for file in /tmp/chip_*; do
if [ -e "$file" ]; then
echo "Error: $file should not exist."
exit 1
fi
done

if [ ! -e "${SNAP_COMMON/mnt/chip_*}" ]; then
echo "Error: ${SNAP_COMMON}/mnt/chip_* does not exist."
exit 1
fi

# Check if server initialization is complete for matter-lighting
if ! journalctl --since "$start_time" | grep matter-lighting | grep "CHIP:SVR: Server initialization complete"; then
echo "Error: matter-lighting initialization failed."
exit 1
fi

Loading
Loading