diff mbox series

[meta-swupdate] Add systemd swupdate mechanism for usb media

Message ID 1506198797-29935-1-git-send-email-ayoub.zaki@embexus.com
State Changes Requested
Headers show
Series [meta-swupdate] Add systemd swupdate mechanism for usb media | expand

Commit Message

Ayoub Zaki Sept. 23, 2017, 8:33 p.m. UTC
In case of using swupdate with systemd this add the possibility of
    updating a device automatically upon inserting an usb media containing
    a valid update artifact:

    -swupdate-usb.rules: trigger swupdate-usb@ service by passing device name as argument.
    -swupdate-usb@.service: mount the media device, run swupdate and trigger
                             a reboot after 1 min in case the update is succesful.

    Note that swupdate-usb@.service unit specify swupdate.service as conflict which stop the latter
    when the former service is started.

Signed-off-by: Ayoub Zaki <ayoub.zaki@embexus.com>
---
 recipes-support/swupdate/swupdate.inc                   | 10 +++++++++-
 recipes-support/swupdate/swupdate/swupdate-usb.rules    |  2 ++
 recipes-support/swupdate/swupdate/swupdate-usb@.service | 12 ++++++++++++
 3 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 recipes-support/swupdate/swupdate/swupdate-usb.rules
 create mode 100644 recipes-support/swupdate/swupdate/swupdate-usb@.service

Comments

Stefano Babic Sept. 24, 2017, 8:21 a.m. UTC | #1
Hi Ayoub,

On 23/09/2017 22:33, Ayoub Zaki wrote:
>     In case of using swupdate with systemd this add the possibility of
>     updating a device automatically upon inserting an usb media containing
>     a valid update artifact:
> 
>     -swupdate-usb.rules: trigger swupdate-usb@ service by passing device name as argument.
>     -swupdate-usb@.service: mount the media device, run swupdate and trigger
>                              a reboot after 1 min in case the update is succesful.
> 
>     Note that swupdate-usb@.service unit specify swupdate.service as conflict which stop the latter
>     when the former service is started.

Anyway, there are several scenarios that are not clear to me. As I
understand from your patch and systemd documentation, systemd will kill
SWUpdate when a USB is inserted. If SWUpdate is running and an update is
currently running, this is at least aborted. There is no management of
concurrent update requests, but SWUpdate already supports this.

I had solved this in another way. Instead of starting "/usr/bin/swupdate
-v -i /mnt/*.swu", we could start the "client" tool that sends the SWU
to the running swupdate daemon. There are no conflicts, and concurrency
is managed internally by SWUpdate. That means, if SWUpdate is updating
from another source, maybe from a remote source, a USB update is
rejected without any other inconvenience.

The same is for rebooting the system. Instead of letting this to
systemd, that has no idea if the update was successful or not, we could
start "progress" together with "client", that is "progress -r -w". In
fact, progress will reboot only if the update was successful, not in any
case. In your patch, reboot is executed without respecting SWUpdate's
exit code.

In this way, all conflicts are removed and we can also offer an update
agent able get the new software from all sources.

What do you think ?

Best regards,
Stefano

> 
> Signed-off-by: Ayoub Zaki <ayoub.zaki@embexus.com>
> ---
>  recipes-support/swupdate/swupdate.inc                   | 10 +++++++++-
>  recipes-support/swupdate/swupdate/swupdate-usb.rules    |  2 ++
>  recipes-support/swupdate/swupdate/swupdate-usb@.service | 12 ++++++++++++
>  3 files changed, 23 insertions(+), 1 deletion(-)
>  create mode 100644 recipes-support/swupdate/swupdate/swupdate-usb.rules
>  create mode 100644 recipes-support/swupdate/swupdate/swupdate-usb@.service
> 
> diff --git a/recipes-support/swupdate/swupdate.inc b/recipes-support/swupdate/swupdate.inc
> index 123aa9d..22762b5 100644
> --- a/recipes-support/swupdate/swupdate.inc
> +++ b/recipes-support/swupdate/swupdate.inc
> @@ -11,6 +11,8 @@ SRC_URI = "git://github.com/sbabic/swupdate.git;protocol=git \
>       file://defconfig \
>       file://swupdate \
>       file://swupdate.service \
> +     file://swupdate-usb.rules \
> +     file://swupdate-usb@.service \
>       "
>  
>  SRCREV = "${AUTOREV}"
> @@ -114,9 +116,15 @@ do_install () {
>  
>    install -d ${D}${systemd_unitdir}/system
>    install -m 644 ${WORKDIR}/swupdate.service ${D}${systemd_unitdir}/system
> +  install -m 644 ${WORKDIR}/swupdate-usb@.service ${D}${systemd_unitdir}/system/
> +
> +  if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
> +    install -d ${D}${sysconfdir}/udev/rules.d
> +    install -m 0644 ${WORKDIR}/swupdate-usb.rules ${D}${sysconfdir}/udev/rules.d/
> +  fi
>  }
>  
>  INITSCRIPT_NAME = "swupdate"
>  INITSCRIPT_PARAMS = "defaults 70"
>  
> -SYSTEMD_SERVICE_${PN} = "swupdate.service"
> +SYSTEMD_SERVICE_${PN} = "swupdate.service swupdate-usb@.service"
> diff --git a/recipes-support/swupdate/swupdate/swupdate-usb.rules b/recipes-support/swupdate/swupdate/swupdate-usb.rules
> new file mode 100644
> index 0000000..7a9aa76
> --- /dev/null
> +++ b/recipes-support/swupdate/swupdate/swupdate-usb.rules
> @@ -0,0 +1,2 @@
> +ACTION=="add", KERNEL=="sd*", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem", TAG+="systemd", ENV{SYSTEMD_WANTS}="swupdate-usb@%k.service"
> +
> diff --git a/recipes-support/swupdate/swupdate/swupdate-usb@.service b/recipes-support/swupdate/swupdate/swupdate-usb@.service
> new file mode 100644
> index 0000000..00b851d
> --- /dev/null
> +++ b/recipes-support/swupdate/swupdate/swupdate-usb@.service
> @@ -0,0 +1,12 @@
> +[Unit]
> +Description=usb media swupdate service
> +Conflicts=swupdate.service
> +
> +[Service]
> +Type=oneshot
> +ExecStartPre=/bin/mount /dev/%I /mnt
> +ExecStart=/usr/bin/swupdate -v -i /mnt/*.swu
> +ExecStop=/sbin/shutdown -r 1
> +
> +[Install]
> +WantedBy=multi-user.target
>
Ayoub Zaki Sept. 24, 2017, 3:03 p.m. UTC | #2
Hi Stefano,

> On 23/09/2017 22:33, Ayoub Zaki wrote:
>>      In case of using swupdate with systemd this add the possibility of
>>      updating a device automatically upon inserting an usb media containing
>>      a valid update artifact:
>>
>>      -swupdate-usb.rules: trigger swupdate-usb@ service by passing device name as argument.
>>      -swupdate-usb@.service: mount the media device, run swupdate and trigger
>>                               a reboot after 1 min in case the update is succesful.
>>
>>      Note that swupdate-usb@.service unit specify swupdate.service as conflict which stop the latter
>>      when the former service is started.
> Anyway, there are several scenarios that are not clear to me. As I
> understand from your patch and systemd documentation, systemd will kill
> SWUpdate when a USB is inserted. If SWUpdate is running and an update is
> currently running, this is at least aborted. There is no management of
> concurrent update requests, but SWUpdate already supports this.
>
> I had solved this in another way. Instead of starting "/usr/bin/swupdate
> -v -i /mnt/*.swu", we could start the "client" tool that sends the SWU
> to the running swupdate daemon. There are no conflicts, and concurrency
> is managed internally by SWUpdate. That means, if SWUpdate is updating
> from another source, maybe from a remote source, a USB update is
> rejected without any other inconvenience.
I was not aware about that option before, it is indeed a more elegant 
and convenient way to offer updates through multi-channel sources.
I noticed however a problem when updating using the client:

1) The script inside swu artifact does not run :

root@wandboard:~# swupdate-client -v 
/media/my-image-swu-wandboard-20170923173548.swu
swupdate_async_start returns 1
Now getting status
Status: 1 message: Software Update started !
Status: 2 message: [extract_file_to_tmp] : Found file: filename 
sw-description  size 285
Status: 2 message: [parse_cfg] : Version 0.1.0
Status: 2 message: [parse_images] : Found compressed Image : 
my-image-base-wandboard.ext4.gz in device : /dev/update for handler raw 
(installed from stream)
Status: 2 message: [parse_scripts] : Found Script: update.sh
Status: 2 message: [extract_files] : Found file:  filename update.sh  
size 901 required
Status: 2 message: [extract_files] : Found file:  filename 
my-image-base-wandboard.ext4.gz  size 29217614 required
Status: 2 message: [extract_files] : Installing STREAM 
my-image-base-wandboard.ext4.gz, 29217614 bytes
Status: 2 message: [install_single_image] : Found installer for stream 
my-image-base-wandboard.ext4.gz raw
Status: 2 message: [install_raw_image] : Device /dev/update cannot be 
opened: No such file or directory
Status: 2 message: [install_single_image] : Installer for raw not 
successful !
Status: 4 message: ERROR corelib/stream_interface.c : extract_files : 
262 : Error streaming my-image-base-wandboard.ext4.gz
Status: 4 message: Image invalid or corrupted. Not installing ...
Status: 2 message: [network_initializer] : Main thread sleep again !
Status: 0 message: Waiting for requests...
Swupdate *failed* !

Whereas updating using swupdate instead of the client everything works 
fine:

root@wandboard:~# swupdate -v -i 
/media/my-image-swu-wandboard-20170923173548.swu
Swupdate v2017.7.0

Licensed under GPLv2. See source distribution for detailed copyright 
notices.

Registered handlers:
         archive
         tar
         raw
         rawfile
         lua
         shellscript
         preinstall
         postinstall
         remote
         uboot
         bootloader
Main loop Daemon
[NOTIFY] : SWUPDATE running :  [extract_sw_description] : Found file:
         filename sw-description
         size 285
         checksum 0x4f0c VERIFIED

Version 0.1.0
[NOTIFY] : SWUPDATE running :  [parse_images] : Found compressed Image  
: my-image-base-wandboard.ext4.gz in device : /dev/update for handler 
raw (installed from stream)

[NOTIFY] : SWUPDATE running :  [parse_scripts] : Found Script: update.sh

[NOTIFY] : SWUPDATE running :  [cpio_scan] : Found file:
         filename update.sh
         size 901
         REQUIRED

[NOTIFY] : SWUPDATE running :  [cpio_scan] : Found file:
         filename my-image-base-wandboard.ext4.gz
         size 29217614
         REQUIRED

Warning: Bad CRC, using default environment
[NOTIFY] : SWUPDATE running :  [extract_next_file] : Copied file:
         filename update.sh
         size 901
         checksum 0x11887 VERIFIED

[NOTIFY] : SWUPDATE running :  [execute_shell_script] : Calling shell 
script /tmp/update.sh preinst: return with 0
[NOTIFY] : SWUPDATE running :  [install_single_image] : Found installer 
for stream my-image-base-wandboard.ext4.gz raw
[NOTIFY] : SWUPDATE running :  [execute_shell_script] : Calling shell 
script /tmp/update.sh postinst: return with 0
Software updated successfully
Please reboot the device to start the new software
[NOTIFY] : SWUPDATE successful !

2) second problem is that swupdate-client does not accept wildcard for 
input files : swupdate-client *.swu, but this can be easily fixed in the 
code.

>   
>
> The same is for rebooting the system. Instead of letting this to
> systemd, that has no idea if the update was successful or not, we could
> start "progress" together with "client", that is "progress -r -w". In
> fact, progress will reboot only if the update was successful, not in any
> case. In your patch, reboot is executed without respecting SWUpdate's
> exit code.
|From Systemd man :
ExecStop=|are only executed when the service started successfully first. 
They are not invoked if the service was never started at all, or in case 
its start-up failed

The shutdown/reboot is executed only if swupdate exit successfully so it 
should be fine here.
>
> In this way, all conflicts are removed and we can also offer an update
> agent able get the new software from all sources.
>
> What do you think ?
I think I should first solve the problem with running the script in swu 
described above and resend a patch.

Thank you !

Best regards,
Ayoub
Stefano Babic Sept. 24, 2017, 4 p.m. UTC | #3
Hi Ayoub,

On 24/09/2017 17:03, Ayoub Zaki wrote:
> Hi Stefano,
> 
>> On 23/09/2017 22:33, Ayoub Zaki wrote:
>>>     In case of using swupdate with systemd this add the possibility of
>>>     updating a device automatically upon inserting an usb media containing
>>>     a valid update artifact:
>>>
>>>     -swupdate-usb.rules: trigger swupdate-usb@ service by passing device name as argument.
>>>     -swupdate-usb@.service: mount the media device, run swupdate and trigger
>>>                              a reboot after 1 min in case the update is succesful.
>>>
>>>     Note that swupdate-usb@.service unit specify swupdate.service as conflict which stop the latter
>>>     when the former service is started.
>> Anyway, there are several scenarios that are not clear to me. As I
>> understand from your patch and systemd documentation, systemd will kill
>> SWUpdate when a USB is inserted. If SWUpdate is running and an update is
>> currently running, this is at least aborted. There is no management of
>> concurrent update requests, but SWUpdate already supports this.
>>
>> I had solved this in another way. Instead of starting "/usr/bin/swupdate
>> -v -i /mnt/*.swu", we could start the "client" tool that sends the SWU
>> to the running swupdate daemon. There are no conflicts, and concurrency
>> is managed internally by SWUpdate. That means, if SWUpdate is updating
>> from another source, maybe from a remote source, a USB update is
>> rejected without any other inconvenience.
> I was not aware about that option before, it is indeed a more elegant
> and convenient way to offer updates through multi-channel sources.
> I noticed however a problem when updating using the client:
> 
> 1) The script inside swu artifact does not run :
> 

It is not correct - but pushing a SWU from external source requires to
think differently. If the file is handled directly from SWUpdate, you
can put artifacts in any order. SWUpdate will work with seek and it will
search for preinstall script before installing anything. If we use a
stream, we cannot. The best way we currently have is to embed a LUA
script inside sw-description. This is run always at parse time before
installing anything.

> root@wandboard:~# swupdate-client -v
> /media/my-image-swu-wandboard-20170923173548.swu
> swupdate_async_start returns 1
> Now getting status
> Status: 1 message: Software Update started !
> Status: 2 message: [extract_file_to_tmp] : Found file:  filename
> sw-description  size 285
> Status: 2 message: [parse_cfg] : Version 0.1.0
> Status: 2 message: [parse_images] : Found compressed Image  :
> my-image-base-wandboard.ext4.gz in device : /dev/update for handler raw
> (installed from stream)
> Status: 2 message: [parse_scripts] : Found Script: update.sh
> Status: 2 message: [extract_files] : Found file:  filename update.sh 
> size 901 required
> Status: 2 message: [extract_files] : Found file:  filename
> my-image-base-wandboard.ext4.gz  size 29217614 required
> Status: 2 message: [extract_files] : Installing STREAM
> my-image-base-wandboard.ext4.gz, 29217614 bytes
> Status: 2 message: [install_single_image] : Found installer for stream
> my-image-base-wandboard.ext4.gz raw
> Status: 2 message: [install_raw_image] : Device /dev/update cannot be
> opened: No such file or directory
> Status: 2 message: [install_single_image] : Installer for raw not
> successful !
> Status: 4 message: ERROR corelib/stream_interface.c : extract_files :
> 262 : Error streaming my-image-base-wandboard.ext4.gz
> Status: 4 message: Image invalid or corrupted. Not installing ...
> Status: 2 message: [network_initializer] : Main thread sleep again !
> Status: 0 message: Waiting for requests...
> Swupdate *failed* !
> 
> Whereas updating using swupdate instead of the client everything works
> fine:

That means that your update package does not work from any other source,
too, including Webserver or Hawkbit.

> 
> root@wandboard:~# swupdate -v -i
> /media/my-image-swu-wandboard-20170923173548.swu
> Swupdate v2017.7.0
> 
> Licensed under GPLv2. See source distribution for detailed copyright
> notices.
> 
> Registered handlers:
>         archive
>         tar
>         raw
>         rawfile
>         lua
>         shellscript
>         preinstall
>         postinstall
>         remote
>         uboot
>         bootloader
> Main loop Daemon
> [NOTIFY] : SWUPDATE running :  [extract_sw_description] : Found file:
>         filename sw-description
>         size 285
>         checksum 0x4f0c VERIFIED
> 
> Version 0.1.0
> [NOTIFY] : SWUPDATE running :  [parse_images] : Found compressed Image 
> : my-image-base-wandboard.ext4.gz in device : /dev/update for handler
> raw (installed from stream)
> 
> [NOTIFY] : SWUPDATE running :  [parse_scripts] : Found Script: update.sh
> 
> [NOTIFY] : SWUPDATE running :  [cpio_scan] : Found file:
>         filename update.sh
>         size 901
>         REQUIRED
> 
> [NOTIFY] : SWUPDATE running :  [cpio_scan] : Found file:
>         filename my-image-base-wandboard.ext4.gz
>         size 29217614
>         REQUIRED
> 
> Warning: Bad CRC, using default environment
> [NOTIFY] : SWUPDATE running :  [extract_next_file] : Copied file:
>         filename update.sh
>         size 901
>         checksum 0x11887 VERIFIED
> 
> [NOTIFY] : SWUPDATE running :  [execute_shell_script] : Calling shell
> script /tmp/update.sh preinst: return with 0

It is not a stream, SWUpdate can seek in the file, and it can extract
and run scripts at the early beginning even if the pre-install script is
the last artifact in your SWU.

> [NOTIFY] : SWUPDATE running :  [install_single_image] : Found installer
> for stream my-image-base-wandboard.ext4.gz raw
> [NOTIFY] : SWUPDATE running :  [execute_shell_script] : Calling shell
> script /tmp/update.sh postinst: return with 0
> Software updated successfully
> Please reboot the device to start the new software
> [NOTIFY] : SWUPDATE successful !
> 
> 2) second problem is that swupdate-client does not accept wildcard for
> input files : swupdate-client *.swu, but this can be easily fixed in the
> code.

I am aware of this. Up now, client was just an *example* to show the
usage of the library. client can be extended with the code we already
have in SWUpdate.

> 
>>  
>>
>> The same is for rebooting the system. Instead of letting this to
>> systemd, that has no idea if the update was successful or not, we could
>> start "progress" together with "client", that is "progress -r -w". In
>> fact, progress will reboot only if the update was successful, not in any
>> case. In your patch, reboot is executed without respecting SWUpdate's
>> exit code.
> |From Systemd man :
> ExecStop=| are only executed when the service started successfully
> first. They are not invoked if the service was never started at all, or
> in case its start-up failed
> 
> The shutdown/reboot is executed only if swupdate exit successfully so it
> should be fine here.

ok

>>
>> In this way, all conflicts are removed and we can also offer an update
>> agent able get the new software from all sources.
>>
>> What do you think ?
> I think I should first solve the problem with running the script in swu
> described above and resend a patch.

Reason is clear to me - see above.

Anyway, I think you are using the script just to select stand-by and
running copy. This is solved in SWUpdate using "selections".

Best regards,
Stefano
Ayoub Zaki Sept. 25, 2017, 7:59 a.m. UTC | #4
Hi Stefano
>>> On 23/09/2017 22:33, Ayoub Zaki wrote:
>>>>      In case of using swupdate with systemd this add the possibility of
>>>>      updating a device automatically upon inserting an usb media containing
>>>>      a valid update artifact:
>>>>
>>>>      -swupdate-usb.rules: trigger swupdate-usb@ service by passing device name as argument.
>>>>      -swupdate-usb@.service: mount the media device, run swupdate and trigger
>>>>                               a reboot after 1 min in case the update is succesful.
>>>>
>>>>      Note that swupdate-usb@.service unit specify swupdate.service as conflict which stop the latter
>>>>      when the former service is started.
>>> Anyway, there are several scenarios that are not clear to me. As I
>>> understand from your patch and systemd documentation, systemd will kill
>>> SWUpdate when a USB is inserted. If SWUpdate is running and an update is
>>> currently running, this is at least aborted. There is no management of
>>> concurrent update requests, but SWUpdate already supports this.
>>>
>>> I had solved this in another way. Instead of starting "/usr/bin/swupdate
>>> -v -i /mnt/*.swu", we could start the "client" tool that sends the SWU
>>> to the running swupdate daemon. There are no conflicts, and concurrency
>>> is managed internally by SWUpdate. That means, if SWUpdate is updating
>>> from another source, maybe from a remote source, a USB update is
>>> rejected without any other inconvenience.
>> I was not aware about that option before, it is indeed a more elegant
>> and convenient way to offer updates through multi-channel sources.
>> I noticed however a problem when updating using the client:
>>
>> 1) The script inside swu artifact does not run :
>>
> It is not correct - but pushing a SWU from external source requires to
> think differently. If the file is handled directly from SWUpdate, you
> can put artifacts in any order. SWUpdate will work with seek and it will
> search for preinstall script before installing anything. If we use a
> stream, we cannot. The best way we currently have is to embed a LUA
> script inside sw-description. This is run always at parse time before
> installing anything.
>
>> root@wandboard:~# swupdate-client -v
>> /media/my-image-swu-wandboard-20170923173548.swu
>> swupdate_async_start returns 1
>> Now getting status
>> Status: 1 message: Software Update started !
>> Status: 2 message: [extract_file_to_tmp] : Found file:  filename
>> sw-description  size 285
>> Status: 2 message: [parse_cfg] : Version 0.1.0
>> Status: 2 message: [parse_images] : Found compressed Image  :
>> my-image-base-wandboard.ext4.gz in device : /dev/update for handler raw
>> (installed from stream)
>> Status: 2 message: [parse_scripts] : Found Script: update.sh
>> Status: 2 message: [extract_files] : Found file:  filename update.sh
>> size 901 required
>> Status: 2 message: [extract_files] : Found file:  filename
>> my-image-base-wandboard.ext4.gz  size 29217614 required
>> Status: 2 message: [extract_files] : Installing STREAM
>> my-image-base-wandboard.ext4.gz, 29217614 bytes
>> Status: 2 message: [install_single_image] : Found installer for stream
>> my-image-base-wandboard.ext4.gz raw
>> Status: 2 message: [install_raw_image] : Device /dev/update cannot be
>> opened: No such file or directory
>> Status: 2 message: [install_single_image] : Installer for raw not
>> successful !
>> Status: 4 message: ERROR corelib/stream_interface.c : extract_files :
>> 262 : Error streaming my-image-base-wandboard.ext4.gz
>> Status: 4 message: Image invalid or corrupted. Not installing ...
>> Status: 2 message: [network_initializer] : Main thread sleep again !
>> Status: 0 message: Waiting for requests...
>> Swupdate *failed* !
>>
>> Whereas updating using swupdate instead of the client everything works
>> fine:
> That means that your update package does not work from any other source,
> too, including Webserver or Hawkbit.
You are right in my sw-description streaming was activated:

/installed-directly=true;/

I removed it the flag and everything worked just fine :-)
>
>> root@wandboard:~# swupdate -v -i
>> /media/my-image-swu-wandboard-20170923173548.swu
>> Swupdate v2017.7.0
>>
>> Licensed under GPLv2. See source distribution for detailed copyright
>> notices.
>>
>> Registered handlers:
>>          archive
>>          tar
>>          raw
>>          rawfile
>>          lua
>>          shellscript
>>          preinstall
>>          postinstall
>>          remote
>>          uboot
>>          bootloader
>> Main loop Daemon
>> [NOTIFY] : SWUPDATE running :  [extract_sw_description] : Found file:
>>          filename sw-description
>>          size 285
>>          checksum 0x4f0c VERIFIED
>>
>> Version 0.1.0
>> [NOTIFY] : SWUPDATE running :  [parse_images] : Found compressed Image
>> : my-image-base-wandboard.ext4.gz in device : /dev/update for handler
>> raw (installed from stream)
>>
>> [NOTIFY] : SWUPDATE running :  [parse_scripts] : Found Script: update.sh
>>
>> [NOTIFY] : SWUPDATE running :  [cpio_scan] : Found file:
>>          filename update.sh
>>          size 901
>>          REQUIRED
>>
>> [NOTIFY] : SWUPDATE running :  [cpio_scan] : Found file:
>>          filename my-image-base-wandboard.ext4.gz
>>          size 29217614
>>          REQUIRED
>>
>> Warning: Bad CRC, using default environment
>> [NOTIFY] : SWUPDATE running :  [extract_next_file] : Copied file:
>>          filename update.sh
>>          size 901
>>          checksum 0x11887 VERIFIED
>>
>> [NOTIFY] : SWUPDATE running :  [execute_shell_script] : Calling shell
>> script /tmp/update.sh preinst: return with 0
> It is not a stream, SWUpdate can seek in the file, and it can extract
> and run scripts at the early beginning even if the pre-install script is
> the last artifact in your SWU.
>
>> [NOTIFY] : SWUPDATE running :  [install_single_image] : Found installer
>> for stream my-image-base-wandboard.ext4.gz raw
>> [NOTIFY] : SWUPDATE running :  [execute_shell_script] : Calling shell
>> script /tmp/update.sh postinst: return with 0
>> Software updated successfully
>> Please reboot the device to start the new software
>> [NOTIFY] : SWUPDATE successful !
>>
>> 2) second problem is that swupdate-client does not accept wildcard for
>> input files : swupdate-client *.swu, but this can be easily fixed in the
>> code.
> I am aware of this. Up now, client was just an *example* to show the
> usage of the library. client can be extended with the code we already
> have in SWUpdate.
On command line there is no issue, the problem here is that globs does 
not get expanded when used with Systemd in ExecStart,
A workarround is to use :
ExecStart=/bin/sh -c "swupdate-client -v /mnt/*.swu"

>
>>>   
>>>
>>> The same is for rebooting the system. Instead of letting this to
>>> systemd, that has no idea if the update was successful or not, we could
>>> start "progress" together with "client", that is "progress -r -w". In
>>> fact, progress will reboot only if the update was successful, not in any
>>> case. In your patch, reboot is executed without respecting SWUpdate's
>>> exit code.
>> |From Systemd man :
>> ExecStop=| are only executed when the service started successfully
>> first. They are not invoked if the service was never started at all, or
>> in case its start-up failed
>>
>> The shutdown/reboot is executed only if swupdate exit successfully so it
>> should be fine here.
> ok
>
>>> In this way, all conflicts are removed and we can also offer an update
>>> agent able get the new software from all sources.
>>>
>>> What do you think ?
>> I think I should first solve the problem with running the script in swu
>> described above and resend a patch.
> Reason is clear to me - see above.
>
> Anyway, I think you are using the script just to select stand-by and
> running copy. This is solved in SWUpdate using "selections".
I'm aware about selections option but I wanted to keep sw-description 
generic for different Hardware configurations
and let pre-install script to prepare and set the updated device node 
before starting the process.

Best regards,
Ayoub
Stefano Babic Sept. 25, 2017, 8:14 a.m. UTC | #5
Hi Ayoub,

On 25/09/2017 09:59, Ayoub Zaki wrote:

>> That means that your update package does not work from any other source,
>> too, including Webserver or Hawkbit.
> You are right in my sw-description streaming was activated:
> 
> /installed-directly=true;/
> 
> I removed it the flag and everything worked just fine :-)

Fine :-)

>>> 2) second problem is that swupdate-client does not accept wildcard for
>>> input files : swupdate-client *.swu, but this can be easily fixed in the
>>> code.
>> I am aware of this. Up now, client was just an *example* to show the
>> usage of the library. client can be extended with the code we already
>> have in SWUpdate.
> On command line there is no issue, the problem here is that globs does
> not get expanded when used with Systemd in ExecStart,
> A workarround is to use :
> ExecStart=/bin/sh -c "swupdate-client -v /mnt/*.swu"
> 
>>
>>>>  
>>>> The same is for rebooting the system. Instead of letting this to
>>>> systemd, that has no idea if the update was successful or not, we could
>>>> start "progress" together with "client", that is "progress -r -w". In
>>>> fact, progress will reboot only if the update was successful, not in
>>>> any
>>>> case. In your patch, reboot is executed without respecting SWUpdate's
>>>> exit code.
>>> |From Systemd man :
>>> ExecStop=| are only executed when the service started successfully
>>> first. They are not invoked if the service was never started at all, or
>>> in case its start-up failed
>>>
>>> The shutdown/reboot is executed only if swupdate exit successfully so it
>>> should be fine here.
>> ok
>>
>>>> In this way, all conflicts are removed and we can also offer an update
>>>> agent able get the new software from all sources.
>>>>
>>>> What do you think ?
>>> I think I should first solve the problem with running the script in swu
>>> described above and resend a patch.
>> Reason is clear to me - see above.
>>
>> Anyway, I think you are using the script just to select stand-by and
>> running copy. This is solved in SWUpdate using "selections".
> I'm aware about selections option but I wanted to keep sw-description
> generic for different Hardware configurations
> and let pre-install script to prepare and set the updated device node
> before starting the process.

Of course, this is also a suitable way - you can select the best
approach for your project :-).

Best regards,
Stefano
diff mbox series

Patch

diff --git a/recipes-support/swupdate/swupdate.inc b/recipes-support/swupdate/swupdate.inc
index 123aa9d..22762b5 100644
--- a/recipes-support/swupdate/swupdate.inc
+++ b/recipes-support/swupdate/swupdate.inc
@@ -11,6 +11,8 @@  SRC_URI = "git://github.com/sbabic/swupdate.git;protocol=git \
      file://defconfig \
      file://swupdate \
      file://swupdate.service \
+     file://swupdate-usb.rules \
+     file://swupdate-usb@.service \
      "
 
 SRCREV = "${AUTOREV}"
@@ -114,9 +116,15 @@  do_install () {
 
   install -d ${D}${systemd_unitdir}/system
   install -m 644 ${WORKDIR}/swupdate.service ${D}${systemd_unitdir}/system
+  install -m 644 ${WORKDIR}/swupdate-usb@.service ${D}${systemd_unitdir}/system/
+
+  if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
+    install -d ${D}${sysconfdir}/udev/rules.d
+    install -m 0644 ${WORKDIR}/swupdate-usb.rules ${D}${sysconfdir}/udev/rules.d/
+  fi
 }
 
 INITSCRIPT_NAME = "swupdate"
 INITSCRIPT_PARAMS = "defaults 70"
 
-SYSTEMD_SERVICE_${PN} = "swupdate.service"
+SYSTEMD_SERVICE_${PN} = "swupdate.service swupdate-usb@.service"
diff --git a/recipes-support/swupdate/swupdate/swupdate-usb.rules b/recipes-support/swupdate/swupdate/swupdate-usb.rules
new file mode 100644
index 0000000..7a9aa76
--- /dev/null
+++ b/recipes-support/swupdate/swupdate/swupdate-usb.rules
@@ -0,0 +1,2 @@ 
+ACTION=="add", KERNEL=="sd*", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem", TAG+="systemd", ENV{SYSTEMD_WANTS}="swupdate-usb@%k.service"
+
diff --git a/recipes-support/swupdate/swupdate/swupdate-usb@.service b/recipes-support/swupdate/swupdate/swupdate-usb@.service
new file mode 100644
index 0000000..00b851d
--- /dev/null
+++ b/recipes-support/swupdate/swupdate/swupdate-usb@.service
@@ -0,0 +1,12 @@ 
+[Unit]
+Description=usb media swupdate service
+Conflicts=swupdate.service
+
+[Service]
+Type=oneshot
+ExecStartPre=/bin/mount /dev/%I /mnt
+ExecStart=/usr/bin/swupdate -v -i /mnt/*.swu
+ExecStop=/sbin/shutdown -r 1
+
+[Install]
+WantedBy=multi-user.target