Best practice to auto-enable custom init.d script w/ ImageBuilder?

'allo everyone,

I'm trying to include an init.d script in an image I build with Image Builder and have it automatically enabled after upgrade. So far I tried to include the init.d script with the files, but unlike other init.d scripts that come with packages it wouldn't be enabled after the image is flashed.

Of course I could include a script that enables the init.d script in uci-defaults, or I could forego my init.d script in lieu of rc.local, but both seem a bit unelegant to me. Is there a better way to enable my init.d script after upgrade?

If you run your script on your build (not target) device, does it produce any errors?

It's been a while ago since I've done this, so I could be mistaken, but I believe it could be because during packaging into the image, the builder attempts to source/execute the script on the build device and if it fails, it is not then automatically symlinked into /etc/rc.d and hence not executed in the image.

@hnyman -- did I ask you this question a few years ago? :wink:

Can you show the init script to us?
And explain how you are including it? (as a custom file?)

My first guess is that the script is malformed and does not contain a START value, does not reference rc.common, or something similar. Then the rc.d symlink is not created.

To be honest, I am not quite sure if adding it as a custom file will work, as I don't remember if the custom files are copied before the init.d rc.d symlink creation in the imagebuilder process. If you are trying to include it as a custom file via FILES, you might also trying creating the symlink in /etc/rc.d and copying that.

Symlink creation in a uci-defaults script is probably the easiest method for you.

/etc/init.d/PACKAGE_X enable

Assume the following:

#!/bin/sh /etc/rc.common

START=90
STOP=10

start() {
    logger "test starting"
}

stop() {
    logger "test stopping"
}

Yes, this is deliberately bare-bones. It's a general question not related to the script itself.

Yes, as a custom file. My question is: Is there something "easier" or more straightforward than compiling an ipk and submitting it to the Image Builder, or more elegant than aftermarket-enabling an init.d script through uci-defaults. Some forum posts suggest chmod'ing it to +x in the FILES directory would lead to auto-enabling after upgrade, but that didn't make any difference for me, it may only apply to a proper build process, not to the Image Builder.

Serious giggling, then?
Surprisingly many problems here are actually due to something simple being forgotten. Or some basic personal tweak not explained in the question, although that tweak is just the singular factor causing the problem. The question was just meant for clarifying the basics. But feel free to feel offended if that makes you happy.

I don't really think that you have too many available options. You have already found the available easy options, although you seem to think them as unelegant.

Some reasoning:

Firstly, init script handling is tightly tied to "packages" during the compilation process. So, you shouldn't expect package-like behavior from files not processed via the package Makefile build process.

Secondly, the whole imagebuilder process is just a simplification of compilation process, and is meant for cooking up the firmware from the ready-made basic firmware and ready package .ipks. It is not meant to replace the whole toolchain & Makefile based compilation process. When a package is included in the image, its enable function is called via default_postinst in \lib\functions.sh and the rc.d symlink is crated. As your file is not formally a package, that never happens.

I think that the two easy options are the ones that you mentioned in your first message:

  • a uci-defaults script where you enable the package. Once done, if should be just like any other package
  • using /etc/rc.local file to start the package

The complicated alternative is to make a proper package and compile an .ipk to be installed. But then you likely need to include that package in the package list for imagebuilder. Not quite sure how to do that, as I don't use imagebuilder myself (as using the full toolchain is simple enough).

A hack would be to pass both the init script (chmodded executable) and the rc.d symlink to that in FILES, but I have no idea if that would work in real world.

But these latter options are either unnecessarily complicated or hack-like compared to the elegant uci-defaults alternative.

Sorry, I was in a bit of a weird mood yesterday. No offense taken. I think I was just a bit miffed that the first assumption is that there's something wrong with the init.d script, since even a completely correct one would not do what I seek it to do in this context.

That was my estimation too, thank you for confirming that.

"Compiling" an .ipk is not particularly hard if it doesn't contain binaries, it's actually just a tar file with predefined structure. So I think I will go down this route, especially since I want to supply a UCI-formatted config file and, after upgrading, keep the enabled/disabled state.

Thank you for your help.

Late to the party, but solved this an hour ago. Here's my solution to add a /etc/uci-defaults/ script which correctly creates the /etc/init.d/ service in the way, symlinks are correct and the service is started after the flash.

ref: https://github.com/Catfriend1/openwrt-presence/blob/master/scripts/imagebuilder/imagebuilder-files/etc/uci-defaults/99-ath9k-set-txq-memory-limit

The script is included via ImageBuilder's "FILES=/path/to/fileroot/" parameter. (See ImageBuilder: how to edit /etc/rc.local - #3 by hackerb9 )

always just included 'files/etc/init.d/SCRIPT' for this... imagebuilder will auto-enable
(at least for the 16ish months do date)

2 Likes

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.