Note: This bug is displayed in read-only format because the product is no longer active in Red Hat Bugzilla.

Bug 1184515

Summary: [RFE] Forward exit code
Product: Red Hat Software Collections Reporter: Vít Ondruch <vondruch>
Component: doc-Packaging_GuideAssignee: Petr Kovar <pkovar>
Status: CLOSED CURRENTRELEASE QA Contact:
Severity: unspecified Docs Contact:
Priority: medium    
Version: unspecifiedCC: bkabrda, jhradile, jstribny, jzeleny, lkardos, vondruch
Target Milestone: ---Keywords: FutureFeature, Reopened
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Enhancement
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-04-23 15:45:11 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Vít Ondruch 2015-01-21 15:25:52 UTC
Description of problem:
scl scriptlets should forward the exit code of the script. For example, this snippet we are using in .spec file's %check section to execute test suite:

%{?scl:scl enable %scl - << \EOF}
RUBYOPT=-I.:lib ruby -e "Dir.glob('./test/test-*.rb').each {|t| require t}" \
  | grep "159 tests, 237 assertions, 1 failures, 0 errors, 0 skips"
%{?scl:EOF}

The issue is that although this fails for non-scl build, the scl build passes, since the inner script exit code is not forwarded.


Version-Release number of selected component (if applicable):

$ rpm -q scl-utils
scl-utils-20130529-14.el7_0.x86_64

How reproducible:


Steps to Reproduce:
1.
2.
3.

Actual results:
SCL build passes while non-SCL build fails.

Expected results:
Build always fails, since the exit code should be forwarded.


Additional info:

Comment 1 Ľuboš Kardoš 2015-01-21 16:39:20 UTC
I tried following:

# scl enable ruby193 - <<\EOF
true
EOF
# echo $?
0
# scl enable ruby193 - <<\EOF
false
EOF
# echo $?
1

It seems that exit code is forwarded. Maybe I don't understand where is the problem. Try to be more precise in how to reproduce the problem. Thanks.

Comment 3 Josef Stribny 2015-01-22 09:57:17 UTC
Actually the problem is somewhere else:

%check
%{?scl:scl enable %scl - << \EOF}
export GEM_PATH=%{buildroot}%{gem_dir}:%{gem_dir}
export PATH=%{buildroot}%{_bindir}:$PATH

pushd %{buildroot}%{gem_instdir}
tar xzf %{SOURCE1}
# test_untabify2(MainTest) test fails. It is not obvious how to make it run
# with Psych, since Psych by design denies tabified YAML, where it was
# acceptable for Syck (if I am not mistaken).
RUBYOPT=-I.:lib ruby -e "Dir.glob('./test/test-*.rb').each {|t| require t}" \
   | grep "159 tests, 237 assertions, 1 failures, 0 errors, 0 skips"
popd
%{?scl:EOF}

See that we are using pushd and popd and even though the test fails the script continues and return success at the end. The workaround is to use something like:

pushd 
runtests || exit 1
popd

Comment 4 Ľuboš Kardoš 2015-01-22 10:10:47 UTC
You have something similar in your spec:

%{?scl:scl enable %scl - << \EOF}
pushd %{buildroot}%{gem_instdir}
RUBYOPT=-I.:lib ruby -e "Dir.glob('./test/test-*.rb').each {|t| require t}" \
  | grep "159 tests, 237 assertions, 1 failures, 0 errors, 0 skips"
popd
%{?scl:EOF}

The last command in script passed to scl is popd. Command popd returns 0 so whole script returns 0 and that's why scl returns 0. But you can use "set -e" in order to make script fail if any command in scripts fails. Rpm set this flag for script in %check section that's why your check script without "scl wapper" works.

So this is not scl bug. You would have the same problem If you used e.g. this wrapper:

bash << \EOF
pushd %{buildroot}%{gem_instdir}
RUBYOPT=-I.:lib ruby -e "Dir.glob('./test/test-*.rb').each {|t| require t}" \
  | grep "159 tests, 237 assertions, 1 failures, 0 errors, 0 skips"
popd
EOF

Comment 5 Vít Ondruch 2015-01-22 11:32:13 UTC
(In reply to Ľuboš Kardoš from comment #4)
> But you can use "set -e" in order to make script fail if any command in scripts fails.

Ok, where can I set this? Why is this not default?

Comment 6 Ľuboš Kardoš 2015-01-22 12:08:19 UTC
In this way:
%{?scl:scl enable %scl - << \EOF}
set -e

pushd %{buildroot}%{gem_instdir}
RUBYOPT=-I.:lib ruby -e "Dir.glob('./test/test-*.rb').each {|t| require t}" \
  | grep "159 tests, 237 assertions, 1 failures, 0 errors, 0 skips"
popd
%{?scl:EOF}

It is option of shell. It is not set by default in normal shell and I am sure we don't want to set it in scl shell either. Because some scripts may stop working. These scripts would work in normal shell (-e not set) but they wouldn't work in scl shell (-e set). The opposite of your problem when you script works in rpm shell (-e set) but it don't work in scl shell (-e not set).

By normal shell I mean shell that is started in terminal.

Comment 7 Vít Ondruch 2015-01-22 12:33:39 UTC
Would you mind to document this somewhere?

Comment 8 Vít Ondruch 2015-01-22 12:34:47 UTC
Or better, is there way for scl-utils to detect that they are running in rpm-build environment and set this automatically in this case?

Comment 9 Ľuboš Kardoš 2015-01-28 09:02:07 UTC
In scl-2 you can use command "scl load" which loads collection into shell and if "-e" was set in shell then it remains set after loading collection. Then your script will look like this:

%{?scl:scl load %scl}
pushd %{buildroot}%{gem_instdir}
RUBYOPT=-I.:lib ruby -e "Dir.glob('./test/test-*.rb').each {|t| require t}" \
  | grep "159 tests, 237 assertions, 1 failures, 0 errors, 0 skips"
popd

And we don't plan to do any fix for this in scl-1 because it will be replaced with scl-2 in short time.

Comment 10 Vít Ondruch 2015-01-28 09:05:23 UTC
Thanks. That looks neat. So the comment #7 is still valid, is this documented somewhere?

Comment 11 Ľuboš Kardoš 2015-01-28 09:36:22 UTC
I had a look at the documentation and it seems it isn't documented anywhere. So I move this bug to scl packaging guide and please document it. Probably somewhere in section "Converting a Conventional Spec File". Show how to convert script by wrapping it into:
%{?scl:scl enable %scl - << \EOF}
set -e

%{?scl:EOF}

and emphasize that is important to set -e to keep behaviour of script without wrapper executed in rpmbuild environment.

Comment 13 Petr Kovar 2015-04-16 16:53:48 UTC
(In reply to Ľuboš Kardoš from comment #11)
> I had a look at the documentation and it seems it isn't documented anywhere.
> So I move this bug to scl packaging guide and please document it. Probably
> somewhere in section "Converting a Conventional Spec File". Show how to
> convert script by wrapping it into:
> %{?scl:scl enable %scl - << \EOF}
> set -e
> 
> %{?scl:EOF}
> 
> and emphasize that is important to set -e to keep behaviour of script
> without wrapper executed in rpmbuild environment.

Ahoj Lubos,

I've updated the doc per your comment. I've actually added a new section about converting RPM scripts:

http://jenkinscat.gsslab.pnq.redhat.com:8080/job/doc-Red_Hat_Software_Collections-Packaging_Guide%20%28html-single%29/lastStableBuild/artifact/tmp/en-US/html-single/index.html#sect-Converting_RPM_Scripts

Could you please review the section and let me know if there's anything that needs to be corrected or updated?

Thanks a lot!

Comment 14 Ľuboš Kardoš 2015-04-17 07:46:36 UTC
It looks good for me. Vit, do you want to review that section too? because you are original reporter of this bug?

Comment 15 Vít Ondruch 2015-04-17 08:32:53 UTC
LGTM. Thanks.