Skip to content

packaging/scripts: Fix shebang#2100

Open
btriller wants to merge 1 commit intocfengine:masterfrom
btriller:packaging-scripts
Open

packaging/scripts: Fix shebang#2100
btriller wants to merge 1 commit intocfengine:masterfrom
btriller:packaging-scripts

Conversation

@btriller
Copy link

Include script header after type specific scriptlet to ensure type specific shebang is used.

Fixes: 19ccbed ("Adjusted detection of systemd in package scriptlets to handle more valid states")

Include script header after type specific scriptlet to ensure type
specific shebang is used.

Fixes: 19ccbed ("Adjusted detection of systemd in package scriptlets to handle more valid states")
@cf-bottom
Copy link

Thank you for submitting a PR! Maybe @craigcomstock can review this?

@craigcomstock
Copy link
Contributor

@btriller thanks for the contribution, can you describe where and how you saw this as a problem? Thanks!

@btriller
Copy link
Author

btriller commented Feb 3, 2026

@btriller thanks for the contribution, can you describe where and how you saw this as a problem? Thanks!

Debian Trixie/CFEngine Community 3.27.0

% wget -q https://cfengine-package-repos.s3.amazonaws.com/community_binaries/Community-3.27.0/agent_debian13_x86_64/cfengine-community_3.27.0-1.debian13_amd64.deb
% dpkg --control cfengine-community_3.27.0-1.debian13_amd64.deb
% find DEBIAN -type f -perm /111 | xargs head -1
==> DEBIAN/preinst <==
USE_SYSTEMD=0

==> DEBIAN/postrm <==
USE_SYSTEMD=0

==> DEBIAN/prerm <==
USE_SYSTEMD=0

==> DEBIAN/postinst <==
USE_SYSTEMD=0

@btriller
Copy link
Author

btriller commented Feb 3, 2026

I didn't dig deeper but we have some hosts that didn't have cfengine3 service enabled after fresh installation.

@btriller
Copy link
Author

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=622094
It seems that dpkg handles shebang in line 20 by accident in just running postinst script with system's default shell.

/tmp/cfe-install.strace.1674730:execve("/var/lib/dpkg/info/cfengine-community.postinst", ["/var/lib/dpkg/info/cfengine-community.postinst", "configure", "3.27.0-1.debian13"], 0x55b2b4fa5a80 /* 27 vars */) = -1 ENOEXEC (Exec format error)
/tmp/cfe-install.strace.1674730:execve("/bin/sh", ["/bin/sh", "/var/lib/dpkg/info/cfengine-community.postinst", "configure", "3.27.0-1.debian13"], 0x55b2b4fa5a80 /* 27 vars */) = 0
/tmp/cfe-install.strace.1674730:openat(AT_FDCWD, "/var/lib/dpkg/info/cfengine-community.postinst", O_RDONLY) = 3
/tmp/cfe-install.strace.1674730:read(10, "USE_SYSTEMD=0\n_use_systemd=$(command -v systemctl 2>&1 >/dev/null && systemctl is-system-running)\ncase \"$_use_systemd\" in\n  offline|unknown)\n    USE_SYSTEMD=0\n    ;;\n  \"\")\n    USE_SYSTEMD=0\n    ;;\n  *)\n    USE_SYSTEMD=1\n    ;;\nesac\n\nuse_systemd()\n{\n  test $USE_SYSTEMD = 1\n}\n\n#!/bin/sh\n\nPREFIX=/var/cfengine\n\npackage_type()\n{\n  echo deb\n}\n\nos_type()\n{\n  echo debian\n}\n\nrc_d_path()\n{\n  echo \"/etc\"\n}\n\nplatform_service()\n{\n  if use_systemd; then\n    /bin/systemctl \"$2\" \"$1\".service\n  else\n    /etc/init.d/\"$1\" \"$2\"\n  fi\n}\n\nIS_UPGRADE=0\n\ncase \"$1\" in\n  upgrade)\n    IS_UPGRADE=1\n    ;;\n  install|remove|purge)\n    IS_UPGRADE=0\n    ;;\n  configure)\n    # Actually not guaranteed to be correct.\n    IS_UPGRADE=0\n    ;;\n  *)\n    # Various error handling on debian. We ignore it for now.\n    exit 0\n    ;;\nesac\n\nnative_is_upgrade()\n{\n  test $IS_UPGRADE = 1\n}\nset -e\nPKG_TYPE=deb\nSCRIPT_TYPE=postinstall\nPROJECT_TYPE=cfengine-community\nBUILT_ON_OS=debian\nBUILT_ON_OS_VERSION=13\n# postgresql docs, https://www.postgresql.org/docs/cur"..., 8192) = 8192

Copy link
Contributor

@craigcomstock craigcomstock left a comment

Choose a reason for hiding this comment

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

I still don't see any mention of how the as-is code causes a problem. It would be good to mention what caused you to work on this change in the first place. I assume there was a problem you encountered?

# action = <install|remove>
#
# script-header.sh
# <type>-script-common.sh
Copy link
Contributor

Choose a reason for hiding this comment

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

The -script-common.sh relies on use_systemd function in script-header.sh so this change will break things I think.

Rather the fix might be to put the shebang at the top of script-header.sh and leave the order as-is.

Only bff-script-common.sh does not use /bin/sh but rather /usr/bin/ksh so that would need refactoring as well.

Copy link
Author

Choose a reason for hiding this comment

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

But use_systemd is only used after script-header.sh?

% sh -x <<endofscript
\`heredoc> func1() {
\`heredoc>         func2
\`heredoc> }
\`heredoc>
\`heredoc> func2() {
\`heredoc>         echo func2
\`heredoc> }
\`heredoc>
\`heredoc> func1
\`heredoc> endofscript
+ func1
+ func2
+ echo func2
func2

Copy link
Contributor

Choose a reason for hiding this comment

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

I will double check this situation. Thanks!

@btriller
Copy link
Author

I still don't see any mention of how the as-is code causes a problem. It would be good to mention what caused you to work on this change in the first place. I assume there was a problem you encountered?

My issue arises from installing cfengine-community package in Debian installer. It isn't running under systemd and so postinst script is using update-rc.d then. But update-rc.d enables only SysV init scripts which are ignored by systemd
if there's a systemd unit for that service as well.
I see how reordering script templates won't fix that issue, but that was before investigating further.

@craigcomstock
Copy link
Contributor

I still don't see any mention of how the as-is code causes a problem. I
My issue arises from installing cfengine-community package in Debian installer. It isn't running under systemd and so postinst script is using update-rc.d then. But update-rc.d enables only SysV init scripts which are ignored by systemd if there's a systemd unit for that service as well. I see how reordering script templates won't fix that issue, but that was before investigating further.

Perfect! So not working with debian sysvinit? That's something we can test and know is resolved. I will try it out and log a ticket if I can reproduce (I bet I can!).

@craigcomstock
Copy link
Contributor

I still don't see any
My issue arises from installing cfengine-community package in Debian installer. It isn't running under systemd and so postinst script is using update-rc.d then. But update-rc.d enables only SysV init scripts which are ignored by systemd if there's a systemd unit for that service as well. I see how reordering script templates won't fix that issue, but that was before investigating further

I switched a default debian-12 instance to sysvinit, rebooted, installed the recent nightly community package and bootstrapped. all seems well.

Can you describe the problem another way?
Are you saying that our call to update-rc.d does nothing because a systemd unit file is laying around?

I tried running update-rc.d cfengine3 defaults manually after all was well and I see plenty of symlinks to start/stop cfengine3 service at various run levels.

Are you saying that after install you have no rcN.d symlinks for cfengine3?

I will try the install again later and check the state after install to make sure our postinst scripts are working properly.

And, yes, I agree that our shebangs should be at the top of our scriptlets... so some change is needed! Thanks for the contribution/notice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants