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

Add c8y-firmware-plugin #1719

Merged
merged 17 commits into from
Feb 23, 2023
Merged

Conversation

rina23q
Copy link
Member

@rina23q rina23q commented Feb 9, 2023

Proposed changes

This PR should implement as described in the ticket #1696.
The following memo might help you to understand the code better.

  • c8y-firmware-plugin --init creates 3 required directories: /var/tedge/cache, /var/tedge/firmware, and /var/tedge/file-transfer. Make sure that /var/tedge/file-transfer can be also created by tedge-agent upon the first POST request.
  • The downloaded file will be stored in /tmp first, then move to /var/tedge/cache. If /var/tedge/cache doesn't exist, this plugin creates the directory in runtime returns error.
  • The file transfer dir /var/tedge/file-transfer/<child-id>/firmware_update will keep a symlink of the file. If this directory doesn't exist, this plugin creates the directory in runtime. If /var/tedge/file-transfer directory doesn't exist, returns error. /<child-id>/firmware_update directory will be created in runtime.
  • The name of downloaded file and the symlink are sha256 of the file URL from the server (not localhost!).
  • The sha256 field of request and response JSON is the sha256 of file itself. Checksum if they downloaded correct file.
  • The operation timeout is configurable by tedge CLI. e.g. tedge config set firmware.timeout 200 tedge config set firmware.child.update.timeout 200.
  • If status field in the response from child device is invalid but operation ID is correct, the operation status is treated None internally. From user, it will be an error.

NOT in this PR's scope

  • Creation of supported operation file named c8y_Firmware. This will be created by user.
  • Heartbeat from child device to extend the operation timer.
  • Case-insensitive status on child device response.

TODO before merge

  • Add uuid and attempt to operation payload.
  • Add mechanism to read/write a status operation to a file to keep persistent server url - localhost url mapping.
  • Update "after help text". The output of c8y-firmware-plugin --help.
  • Add tests!!!
  • --init creates directories.
  • Error handling. If an error occurs, make c8y_Firmware operation failed.
  • Rename the tedge config key from firmware.timeout to firmware.child.update.timeout.

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Improvement (general improvements like code refactoring that doesn't explicitly fix a bug or add any new functionality)
  • Documentation Update (if none of the other choices apply)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Paste Link to the issue

#1696

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA (in all commits with git commit -s)
  • I ran cargo fmt as mentioned in CODING_GUIDELINES
  • I used cargo clippy as mentioned in CODING_GUIDELINES
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)

Further comments

Directory/file permissions under /var/tedge and its security.

  • /var/tedge is created by tedge-agent --init owned by tedge:tedge.
  • /var/tedge/file-transfer is created by tedge-agent owned by tedge:tedge upon PUT` request. (timing of child device bootstrapping of config plugin)
  • /var/tedge/file-transfer/<child-id> is created by tedge-agent owned by tedge:tedge upon PUT request. (timing of child device bootstrapping of config plugin)
  • /var/tedge/file-transfer/<child-id>/config_update is created by c8y-configuration-plugin owned by root:root.

This plugin needs them. Now c8y-firmware-plugin is supposed to be run by tedge user, therefore, they will be owned by tedge:tedge. But it is a security risk as any one can modify via tedge-agent http server.

  • /var/tedge/cache/<file>
  • /var/tedge/file-transfer/<child-id>/firmware_update/<symlink>

@rina23q rina23q force-pushed the feature/1696/firmware-plugin branch 2 times, most recently from 6388c57 to e953604 Compare February 9, 2023 00:41
The first skeleton to receive SmartREST messages from c8y

Signed-off-by: Rina Fujino <18257209+rina23q@users.noreply.github.com>
Signed-off-by: Rina Fujino <18257209+rina23q@users.noreply.github.com>
@rina23q rina23q force-pushed the feature/1696/firmware-plugin branch 3 times, most recently from bf9a920 to aea4839 Compare February 9, 2023 19:35
Signed-off-by: Rina Fujino <18257209+rina23q@users.noreply.github.com>
@rina23q rina23q force-pushed the feature/1696/firmware-plugin branch 5 times, most recently from 6bdcabe to 9c64424 Compare February 10, 2023 18:17
Copy link
Contributor

@albinsuresh albinsuresh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One aspect that I didn't fully understand from the impl is how the child devices would send their current firmware details to C8Y using the set firmware message? There was some contract for the c8y-config-plugin to send the initial config list to tedge/c8y. Something similar is needed here as well, right?

configuration/debian/c8y-firmware-plugin/prerm Outdated Show resolved Hide resolved
plugins/c8y_firmware_plugin/src/child_device.rs Outdated Show resolved Hide resolved
plugins/c8y_firmware_plugin/src/common.rs Outdated Show resolved Hide resolved
if smartrest_request.device == self.tedge_device_id {
warn!("c8y-firmware-plugin does not support firmware operation for the main tedge device. \
Please define a custom operation handler for the c8y_Firmware operation.");
Ok(())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeing that Ok(()) here surprised me a bit as I thought that it'd make the operation succeed in the cloud. But since that's not the case, it's fine. May be worth adding a comment that we're ignoring this request so that some other plugin on the machine can handle it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be worth adding a comment that we're ignoring this request so that some other plugin on the machine can handle it.

I think it's our basic principle, if plugin doesn't address either parent device or child device, ignore the operations coming from c8y, so that user's custom plugin can consume them.

plugins/c8y_firmware_plugin/src/download.rs Outdated Show resolved Hide resolved
plugins/c8y_firmware_plugin/src/download.rs Outdated Show resolved Hide resolved
Signed-off-by: Rina Fujino <18257209+rina23q@users.noreply.github.com>
- Improve log messages
- Add validation of response from child device
- Add `--init` option as a placeholder for the future enhancements

Signed-off-by: Rina Fujino <18257209+rina23q@users.noreply.github.com>
Signed-off-by: Rina Fujino <18257209+rina23q@users.noreply.github.com>
Signed-off-by: Rina Fujino <18257209+rina23q@users.noreply.github.com>
Signed-off-by: Rina Fujino <18257209+rina23q@users.noreply.github.com>
Signed-off-by: Rina Fujino <18257209+rina23q@users.noreply.github.com>
Copy link
Contributor

@albinsuresh albinsuresh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's still scope for some more refactoring to simplify the error propagation. Failing operations in the cloud is done from multiple places which can be avoided with some error propagation refactoring.

pub default_http_bind_address: IpAddress,

/// Default firmware operation timeout in seconds
pub default_firmware_timeout: Seconds,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub default_firmware_timeout: Seconds,
pub default_firmware_update_timeout: Seconds,

plugins/c8y_firmware_plugin/src/firmware_manager.rs Outdated Show resolved Hide resolved
plugins/c8y_firmware_plugin/src/firmware_manager.rs Outdated Show resolved Hide resolved
plugins/c8y_firmware_plugin/src/firmware_manager.rs Outdated Show resolved Hide resolved
plugins/c8y_firmware_plugin/src/firmware_manager.rs Outdated Show resolved Hide resolved
use tokio::sync::Mutex;

// FIXME!: Think of good text
const AFTER_HELP_TEXT: &str = r#"We will write later!"#;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget ;)

plugins/c8y_firmware_plugin/src/main.rs Outdated Show resolved Hide resolved
plugins/c8y_firmware_plugin/src/firmware_manager.rs Outdated Show resolved Hide resolved
@reubenmiller
Copy link
Contributor

One aspect that I didn't fully understand from the impl is how the child devices would send their current firmware details to C8Y using the set firmware message? There was some contract for the c8y-config-plugin to send the initial config list to tedge/c8y. Something similar is needed here as well, right?

I think we can split the initial setting of the firmware when the child device starts in another PR, as we still need to think about the interface here. In the meantime the child device adapter/connector can update the firmware in the c8y_Firmware fragment via the c8y/inventory/.... topic.

@reubenmiller
Copy link
Contributor

reubenmiller commented Feb 16, 2023

@rina23q Now that #1714 is merged, you will have rebase/merge the changes from main into your branch, as some of the integration test files are not present in your branch which causes the new integration-test workflow to fail.

@@ -58,6 +58,15 @@ pub fn create_directory_with_mode(dir: impl AsRef<Path>, mode: u32) -> Result<()
perm_entry.create_directory(dir.as_ref())
}

pub fn create_file_with_mode(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather create a single create_file function that accepts the user, group and mode as Options. This single function would be used everywhere and would help us avoid having to come up with so many variants like create_file_with_mode and create_file_with_user_group for each combination.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be done independently as this PR is already large.

That said I would suggest yet another direction (for later!). I agree with Albin that we cannot have a method per combination, but I also understand the need for something more explicit than a function with 3 optional arguments. So I would add with_user, with_group and with_mode method to PermissionEntry. So we could write: PermissionEntry::new().with_mode(644).create_file(path, content).

plugins/c8y_firmware_plugin/src/firmware_manager.rs Outdated Show resolved Hide resolved
plugins/c8y_firmware_plugin/src/firmware_manager.rs Outdated Show resolved Hide resolved
plugins/c8y_firmware_plugin/src/firmware_manager.rs Outdated Show resolved Hide resolved
plugins/c8y_firmware_plugin/src/firmware_manager.rs Outdated Show resolved Hide resolved
id: op_id.to_string(),
})
}
fn get_file_path(&self, op_id: &str) -> PathBuf {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fn get_file_path(&self, op_id: &str) -> PathBuf {
fn get_operation_file_path(&self, op_id: &str) -> PathBuf {

To be more contextual.

@@ -598,16 +607,22 @@ pub struct FirmwareOperationEntry {
}

impl FirmwareOperationEntry {
fn create_file(&self) -> Result<(), FirmwareManagementError> {
let path = PersistentStore::get_file_path(&self.operation_id);
fn create_file(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels more like this create_file or rather create_operation_file and overwrite_file functions should have been part of the PresistentStore as creating a file in the store should have been a function of that store.

Comment on lines +33 to +38
// TODO! We should make it configurable by tedge config later.
const PERSISTENT_DIR_PATH: &str = "/var/tedge";

pub const CACHE_DIR_NAME: &str = "cache";
pub const FILE_TRANSFER_DIR_NAME: &str = "file-transfer";
pub const PERSISTENT_STORE_DIR_NAME: &str = "firmware";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These constants better belong on the firmware_manager module itself so that they are portable when we migrate this plugin to the actor model with a different main.

const PERSISTENT_DIR_PATH: &str = "/var/tedge";

pub const CACHE_DIR_NAME: &str = "cache";
pub const FILE_TRANSFER_DIR_NAME: &str = "file-transfer";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO for later: This constant ideally should have been defined in some tedge-api crate so that all plugins using the file-transfer functionality could reuse it.

plugins/c8y_firmware_plugin/src/tests.rs Outdated Show resolved Hide resolved
Signed-off-by: Rina Fujino <18257209+rina23q@users.noreply.github.com>
1. Move the creation of 3 directories (cache, file-transfer, firmware)
to `--init` option.
2. The path of `/var/tedge` is given as argument of FirmwareManager, so
that test can use /tmp directory instead.
3. Remove permission check of persistent store files.
4. Stop using anyhow::Error, instead, FirmwareManagement error is used.

Signed-off-by: Rina Fujino <18257209+rina23q@users.noreply.github.com>
@rina23q
Copy link
Member Author

rina23q commented Feb 17, 2023

@rina23q Now that #1714 is merged, you will have rebase/merge the changes from main into your branch, as some of the integration test files are not present in your branch which causes the new integration-test workflow to fail.

It's done.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 17, 2023

Robot Results

✅ Passed ❌ Failed ⏭️ Skipped Total Pass %
137 0 5 137 100

Passed Tests

Name ⏱️ Duration Suite
Define Child device 1 ID 0.008 s C8Y Child Alarms Rpi
Normal case when the child device does not exist on c8y cloud 2.846 s C8Y Child Alarms Rpi
Normal case when the child device already exists 0.753 s C8Y Child Alarms Rpi
Reconciliation when the new alarm message arrives, restart the mapper 1.25 s C8Y Child Alarms Rpi
Reconciliation when the alarm that is cleared 5.499 s C8Y Child Alarms Rpi
Prerequisite Parent 17.777 s Child Conf Mgmt Plugin
Prerequisite Child 0.326 s Child Conf Mgmt Plugin
Child device bootstrapping 15.504 s Child Conf Mgmt Plugin
Snapshot from device 21.927 s Child Conf Mgmt Plugin
Child device config update 17.024 s Child Conf Mgmt Plugin
Configuration types should be detected on file change (without restarting service) 49.206 s Inotify Crate
Child devices support sending simple measurements 46.034 s Child Device Telemetry
Child devices support sending custom measurements 45.04 s Child Device Telemetry
Child devices support sending custom events 39.734 s Child Device Telemetry
Child devices support sending custom events overriding the type 34.35 s Child Device Telemetry
Child devices support sending custom alarms #1699 32.833 s Child Device Telemetry
Child devices support sending inventory data via c8y topic 23.122 s Child Device Telemetry
Main device support sending inventory data via c8y topic 25.794 s Child Device Telemetry
Successful firmware operation 61.46 s Firmware Operation
Install with empty firmware name 50.552 s Firmware Operation
Supports restarting the device 76.017 s Restart Device
Update tedge version from previous using Cumulocity 98.609 s Tedge Self Update
Successful shell command with output 4.08 s Shell Operation
Check Successful shell command with literal double quotes output 3.363 s Shell Operation
Execute multiline shell command 3.232 s Shell Operation
Failed shell command 3.347 s Shell Operation
Software list should be populated during startup 47.452 s Software
Install software via Cumulocity 65.021 s Software
Software list should only show currently installed software and not candidates 43.234 s Software
Stop tedge-agent service 0.237 s Log Path Config
Customize the log path 0.077 s Log Path Config
Initialize tedge-agent 0.174 s Log Path Config
Check created folders 0.091 s Log Path Config
Remove created custom folders 0.101 s Log Path Config
Install latest via script (from current branch) 28.408 s Install Tedge
Install specific version via script (from current branch) 18.907 s Install Tedge
Install latest tedge via script (from main branch) 20.255 s Install Tedge
Support starting and stopping services 35.32 s Service-Control
Supports a reconnect 43.59 s Test-Commands
Supports disconnect then connect 47.119 s Test-Commands
Update unknown setting 25.938 s Test-Commands
Update known setting 24.267 s Test-Commands
Stop c8y-configuration-plugin 0.15 s Health C8Y-Configuration-Plugin
Update the service file 0.167 s Health C8Y-Configuration-Plugin
Reload systemd files 0.697 s Health C8Y-Configuration-Plugin
Start c8y-configuration-plugin 0.213 s Health C8Y-Configuration-Plugin
Start watchdog service 10.297 s Health C8Y-Configuration-Plugin
Check PID of c8y-configuration-plugin 0.15 s Health C8Y-Configuration-Plugin
Kill the PID 0.222 s Health C8Y-Configuration-Plugin
Recheck PID of c8y-configuration-plugin 2.313 s Health C8Y-Configuration-Plugin
Compare PID change 0.001 s Health C8Y-Configuration-Plugin
Stop watchdog service 0.235 s Health C8Y-Configuration-Plugin
Remove entry from service file 0.144 s Health C8Y-Configuration-Plugin
Stop c8y-log-plugin 0.178 s Health C8Y-Log-Plugin
Update the service file 0.163 s Health C8Y-Log-Plugin
Reload systemd files 0.698 s Health C8Y-Log-Plugin
Start c8y-log-plugin 0.235 s Health C8Y-Log-Plugin
Start watchdog service 10.259 s Health C8Y-Log-Plugin
Check PID of c8y-log-plugin 0.078 s Health C8Y-Log-Plugin
Kill the PID 0.073 s Health C8Y-Log-Plugin
Recheck PID of c8y-log-plugin 2.095 s Health C8Y-Log-Plugin
Compare PID change 0.001 s Health C8Y-Log-Plugin
Stop watchdog service 0.058 s Health C8Y-Log-Plugin
Remove entry from service file 0.058 s Health C8Y-Log-Plugin
Stop tedge-mapper 0.286 s Health Tedge Mapper C8Y
Update the service file 0.127 s Health Tedge Mapper C8Y
Reload systemd files 1.138 s Health Tedge Mapper C8Y
Start tedge-mapper 0.228 s Health Tedge Mapper C8Y
Start watchdog service 10.54 s Health Tedge Mapper C8Y
Check PID of tedge-mapper 0.061 s Health Tedge Mapper C8Y
Kill the PID 0.077 s Health Tedge Mapper C8Y
Recheck PID of tedge-mapper 2.101 s Health Tedge Mapper C8Y
Compare PID change 0.001 s Health Tedge Mapper C8Y
Stop watchdog service 0.067 s Health Tedge Mapper C8Y
Remove entry from service file 0.074 s Health Tedge Mapper C8Y
Stop tedge-agent 0.288 s Health Tedge-Agent
Update the service file 0.093 s Health Tedge-Agent
Reload systemd files 0.548 s Health Tedge-Agent
Start tedge-agent 0.102 s Health Tedge-Agent
Start watchdog service 10.27 s Health Tedge-Agent
Check PID of tedge-mapper 0.061 s Health Tedge-Agent
Kill the PID 0.064 s Health Tedge-Agent
Recheck PID of tedge-agent 2.149 s Health Tedge-Agent
Compare PID change 0.001 s Health Tedge-Agent
Stop watchdog service 0.088 s Health Tedge-Agent
Remove entry from service file 0.069 s Health Tedge-Agent
Stop tedge-mapper-az 0.27 s Health Tedge-Mapper-Az
Update the service file 0.156 s Health Tedge-Mapper-Az
Reload systemd files 0.859 s Health Tedge-Mapper-Az
Start tedge-mapper-az 0.234 s Health Tedge-Mapper-Az
Start watchdog service 10.236 s Health Tedge-Mapper-Az
Check PID of tedge-mapper-az 0.13 s Health Tedge-Mapper-Az
Kill the PID 0.177 s Health Tedge-Mapper-Az
Recheck PID of tedge-agent 2.194 s Health Tedge-Mapper-Az
Compare PID change 0.001 s Health Tedge-Mapper-Az
Stop watchdog service 0.157 s Health Tedge-Mapper-Az
Remove entry from service file 0.143 s Health Tedge-Mapper-Az
Stop tedge-mapper-collectd 0.162 s Health Tedge-Mapper-Collectd
Update the service file 0.147 s Health Tedge-Mapper-Collectd
Reload systemd files 0.747 s Health Tedge-Mapper-Collectd
Start tedge-mapper-collectd 0.168 s Health Tedge-Mapper-Collectd
Start watchdog service 10.268 s Health Tedge-Mapper-Collectd
Check PID of tedge-mapper-collectd 0.254 s Health Tedge-Mapper-Collectd
Kill the PID 0.128 s Health Tedge-Mapper-Collectd
Recheck PID of tedge-mapper-collectd 2.184 s Health Tedge-Mapper-Collectd
Compare PID change 0.001 s Health Tedge-Mapper-Collectd
Stop watchdog service 0.151 s Health Tedge-Mapper-Collectd
Remove entry from service file 0.133 s Health Tedge-Mapper-Collectd
c8y-log-plugin health status 5.6530000000000005 s MQTT health endpoints
c8y-configuration-plugin health status 5.503 s MQTT health endpoints
Wrong package name 0.123 s Improve Tedge Apt Plugin Error Messages
Wrong version 0.223 s Improve Tedge Apt Plugin Error Messages
Wrong type 0.251 s Improve Tedge Apt Plugin Error Messages
tedge_connect_test_positive 0.556 s Tedge Connect Test
tedge_connect_test_negative 0.629 s Tedge Connect Test
tedge_connect_test_sm_services 7.096 s Tedge Connect Test
tedge_disconnect_test_sm_services 0.352 s Tedge Connect Test
Install thin-edge.io 12.836 s Call Tedge
call tedge -V 0.063 s Call Tedge
call tedge -h 0.076 s Call Tedge
call tedge -h -V 0.12 s Call Tedge
call tedge help 0.076 s Call Tedge
tedge config list 0.107 s Call Tedge Config List
tedge config list --all 0.079 s Call Tedge Config List
set/unset device.type 0.333 s Call Tedge Config List
set/unset device.key.path 0.379 s Call Tedge Config List
set/unset device.cert.path 0.457 s Call Tedge Config List
set/unset c8y.root.cert.path 0.417 s Call Tedge Config List
set/unset c8y.smartrest.templates 0.289 s Call Tedge Config List
set/unset az.root.cert.path 0.341 s Call Tedge Config List
set/unset az.mapper.timestamp 0.415 s Call Tedge Config List
set/unset mqtt.bind_address 0.314 s Call Tedge Config List
set/unset mqtt.port 0.398 s Call Tedge Config List
set/unset tmp.path 0.533 s Call Tedge Config List
set/unset logs.path 0.568 s Call Tedge Config List
set/unset run.path 0.438 s Call Tedge Config List
Get Put Delete 3.432 s Http File Transfer Api

- Improve error handling
- Add more integration tests

Signed-off-by: Rina Fujino <18257209+rina23q@users.noreply.github.com>
@rina23q rina23q temporarily deployed to Test Pull Request February 17, 2023 22:07 — with GitHub Actions Inactive
@rina23q rina23q marked this pull request as ready for review February 17, 2023 22:12
@rina23q
Copy link
Member Author

rina23q commented Feb 17, 2023

I believe now this PR needs only minor fixes, therefore, change the state from Draft to Open.

plugins/c8y_firmware_plugin/src/tests.rs Show resolved Hide resolved
plugins/c8y_firmware_plugin/src/tests.rs Outdated Show resolved Hide resolved
plugins/c8y_firmware_plugin/src/tests.rs Outdated Show resolved Hide resolved
plugins/c8y_firmware_plugin/src/tests.rs Outdated Show resolved Hide resolved
plugins/c8y_firmware_plugin/src/tests.rs Outdated Show resolved Hide resolved
.await?;

// Assert the c8y_Firmware operation status mapping to EXECUTING(501) and FAILED(502)
mqtt_tests::assert_received_all_expected(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't you need to make sure that the timeout period has elapsed before doing this assertion? With a sleep may be.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The firmware response timeout is 1 sec. We wait 5 seconds to check if all expected message are received inside assert. I don't think we need sleep.

plugins/c8y_firmware_plugin/src/tests.rs Show resolved Hide resolved
plugins/c8y_firmware_plugin/src/tests.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@didier-wenzek didier-wenzek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds good and ready to be merged.

Just need to provide some proper help text.

@@ -58,6 +58,15 @@ pub fn create_directory_with_mode(dir: impl AsRef<Path>, mode: u32) -> Result<()
perm_entry.create_directory(dir.as_ref())
}

pub fn create_file_with_mode(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be done independently as this PR is already large.

That said I would suggest yet another direction (for later!). I agree with Albin that we cannot have a method per combination, but I also understand the need for something more explicit than a function with 3 optional arguments. So I would add with_user, with_group and with_mode method to PermissionEntry. So we could write: PermissionEntry::new().with_mode(644).create_file(path, content).

Ok(())
}

// TODO: Move some to functions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this now with 813e745!

@rina23q rina23q temporarily deployed to Test Pull Request February 22, 2023 16:32 — with GitHub Actions Inactive
@rina23q
Copy link
Member Author

rina23q commented Feb 22, 2023

This can be done independently as this PR is already large.

That said I would suggest yet another direction (for later!). I agree with Albin that we cannot have a method per combination, but I also understand the need for something more explicit than a function with 3 optional arguments. So I would add with_user, with_group and with_mode method to PermissionEntry. So we could write: PermissionEntry::new().with_mode(644).create_file(path, content).

It sounds good. I'd like to address in next PR!

Signed-off-by: Rina Fujino <18257209+rina23q@users.noreply.github.com>
- Revert the ResponsePayload.status to non Option type.
- Change the type of http_proxy as only one http_proxy is used.
- handle_child_device_firmware_update_response() publishes mqtt messages
directly inside the function.

Signed-off-by: Rina Fujino <18257209+rina23q@users.noreply.github.com>
Signed-off-by: Rina Fujino <18257209+rina23q@users.noreply.github.com>
@rina23q rina23q temporarily deployed to Test Pull Request February 23, 2023 15:49 — with GitHub Actions Inactive
@rina23q rina23q merged commit 54632d1 into thin-edge:main Feb 23, 2023
@rina23q rina23q deleted the feature/1696/firmware-plugin branch February 23, 2023 16:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants