Hi Carlos,
I wrote up a script that automates some bits of the process of importing tarballs from upstream master into rawhide. I've attached the script for your review. Do you think this would be useful to have in the fedora rawhide branch? With its presence, the workflow for resyncing rawhide would simply be:
0. Check out the master branch on the local glibc repo 1. Check out the master branch on the fedora glibc repo 2. In fedora glibc, run:
./sync-upstream.sh <path-to-local-glibc-repo>
3.1. If the script succeeds:
fedpkg push fedpkg build
3.2. If the script fails, analyze the reason for failure and fall back to manual process. The most likely failure is that a patch refuses to apply and one may have to adjust the patch before committing the changes.
Let me know what you think about this.
Siddhesh
#!/bin/sh # Given a git source repo, generate a tarball from master, modify the spec file # and upload it to lookaside cache if the tarball unpacks and gets patched # cleanly. This currently needs the source repo to be on the master branch. # XXX In future, we could just do the git-archive ourselves instead of relying # on the makefile bits. That way we don't have to waste time waiting for the # bzip and xz archives that we don't use.
if [ $# -ne 1 ]; then echo "Usage: $0 <path-to-upstream-repo>" 1>&2 exit 1 fi
upstream=$1
tmpdir=/tmp/tmp-rawhide-gzbuild srcdir=$(git --git-dir=$upstream/.git describe) cursrc=$(sed -ne 's/^%define glibcsrcdir (.*)/\1/p' glibc.spec)
if [ "$cursrc" = "$srcdir" ]; then echo Already in sync with upstream exit 0 fi
echo "+ Generating tarballs..." mkdir $tmpdir pushd $tmpdir # We don't need any options here since we only want the makefile to be # generated so that we can call make dist $upstream/configure --prefix=/usr # HACK! We don't want to regenerate the INSTALL file, so regenerate the file # explicitly, undo its changes and then make dist. That way make thinks that # INSTALL is up-to-date. make INSTALL pushd $upstream git diff INSTALL | patch -p1 -R popd make dist popd rm -rf $tmpdir
if ! [ -f $upstream/$srcdir.tar.gz ]; then echo "Failed to create the tarball" exit 2 fi
# Copy over the tarball. echo "+ Copying over generated tarball..." cp $upstream/$srcdir.tar.gz ./
# Our changelog header cldate=$(date +'%a %b %d %Y') clname=$(git config --get user.name) clemail=$(git config --get user.email | sed 's/@/\@/')
# Getting our version and release number from the spec file. nv=$(perl -ne 's/^%define glibcversion (.+)/printf("%s-", $1)/e;' \ -e 's/^%define glibcrelease ([0-9]+).*/printf("%d\n", $1 + 1)/e;' \ glibc.spec)
# Our changelog entry. changelog="* $cldate $clname <$clemail> - $nv\n- Sync with upstream master.\n"
# Change the glibcsrcdir variable, bump up the release number and add an extra # entry to the changelog. echo "+ Updating spec file..." perl -pi \ -e "s/^(%define glibcsrcdir ).+/$1$srcdir/; s/^(%define glibcrelease )(\d+)/print($1); print($2 + 1);'';/e; s/^(%changelog)$/$1\n$changelog/" \ glibc.spec
echo "Testing if fedpkg prep works..." if fedpkg prep; then echo "Source prep is clean, so we're good to go." fedpkg new-sources $srcdir.tar.gz git commit -a -m "Sync with upstream master" # XXX I don't have the courage yet to do a fedpkg push && fedpkg build # from the script. else echo "Source prep failed." echo "Check the output above and fix things before committing." fi
echo "+ Done!"
On 01/23/2014 05:02 AM, Siddhesh Poyarekar wrote:
Hi Carlos,
I wrote up a script that automates some bits of the process of importing tarballs from upstream master into rawhide. I've attached the script for your review. Do you think this would be useful to have in the fedora rawhide branch? With its presence, the workflow for resyncing rawhide would simply be:
Great job!
We should absolutely put this into the Fedora rawhide branch.
We want all of our tools easily accessible on checkout, either from that branch or some Fedora glibc-releng repository.
Honestly I think you should check this into master as an example distribution script for RPM systems. That way others can look at what you've done without needing to go into a distribution specific branch.
It's glibc's responsibility to help downstream distributions use the project effectively.
Check out the master branch on the local glibc repo
Check out the master branch on the fedora glibc repo
In fedora glibc, run:
./sync-upstream.sh <path-to-local-glibc-repo>
3.1. If the script succeeds:
fedpkg push fedpkg build
3.2. If the script fails, analyze the reason for failure and fall back to manual process. The most likely failure is that a patch refuses to apply and one may have to adjust the patch before committing the changes.
Let me know what you think about this.
Sounds good to me.
It's a step in the right direction.
Siddhesh
#!/bin/sh # Given a git source repo, generate a tarball from master, modify the spec file # and upload it to lookaside cache if the tarball unpacks and gets patched # cleanly. This currently needs the source repo to be on the master branch. # XXX In future, we could just do the git-archive ourselves instead of relying
s/XXX/TODO:/g
Prefer TODO over XXX only because it's clear this is an RFE.
I generally reserve XXX and FIXME for something that are wrong.
# on the makefile bits. That way we don't have to waste time waiting for the # bzip and xz archives that we don't use.
if [ $# -ne 1 ]; then echo "Usage: $0 <path-to-upstream-repo>" 1>&2 exit 1 fi
upstream=$1
tmpdir=/tmp/tmp-rawhide-gzbuild
Can't run two on the same machine.
Use mktemp please.
srcdir=$(git --git-dir=$upstream/.git describe) cursrc=$(sed -ne 's/^%define glibcsrcdir (.*)/\1/p' glibc.spec)
These are automatically escaped by the sub-shell invocation.
Assignment also preserves escaping e.g. cursrc2=$cursrc is OK.
if [ "$cursrc" = "$srcdir" ]; then echo Already in sync with upstream exit 0 fi
echo "+ Generating tarballs..." mkdir $tmpdir pushd $tmpdir
These are not and and need escaping now.
# We don't need any options here since we only want the makefile to be # generated so that we can call make dist $upstream/configure --prefix=/usr
Needs escaping e.g. "$upstream/configure"
# HACK! We don't want to regenerate the INSTALL file, so regenerate the file # explicitly, undo its changes and then make dist. That way make thinks that # INSTALL is up-to-date. make INSTALL pushd $upstream git diff INSTALL | patch -p1 -R popd make dist popd rm -rf $tmpdir
Needs escaping e.g. "$tmpdir".
if ! [ -f $upstream/$srcdir.tar.gz ]; then
Needs escaping.
echo "Failed to create the tarball" exit 2 fi
# Copy over the tarball. echo "+ Copying over generated tarball..." cp $upstream/$srcdir.tar.gz ./
Needs escaping.
# Our changelog header cldate=$(date +'%a %b %d %Y') clname=$(git config --get user.name) clemail=$(git config --get user.email | sed 's/@/\@/')
OK.
# Getting our version and release number from the spec file. nv=$(perl -ne 's/^%define glibcversion (.+)/printf("%s-", $1)/e;' \ -e 's/^%define glibcrelease ([0-9]+).*/printf("%d\n", $1 + 1)/e;' \ glibc.spec)
# Our changelog entry. changelog="* $cldate $clname <$clemail> - $nv\n- Sync with upstream master.\n"
# Change the glibcsrcdir variable, bump up the release number and add an extra # entry to the changelog. echo "+ Updating spec file..." perl -pi \ -e "s/^(%define glibcsrcdir ).+/$1$srcdir/; s/^(%define glibcrelease )(\d+)/print($1); print($2 + 1);'';/e; s/^(%changelog)$/$1\n$changelog/" \ glibc.spec
echo "Testing if fedpkg prep works..." if fedpkg prep; then
Run `fedpkg prep' as a distinct step, save the output, and then check the return code.
echo "Source prep is clean, so we're good to go." fedpkg new-sources $srcdir.tar.gz
Needs escaping.
git commit -a -m "Sync with upstream master" # XXX I don't have the courage yet to do a fedpkg push && fedpkg build # from the script.
Do it.
But do three things.
(1) Use `set -e' immediately after #!/bin/sh to ensure that any non-zero exit from any command, builtin, or sub-shell exits the shell.
(2) Make sure you have no compound steps that could hide an exit code. e.g.
[carlos@koi ~]$ cat test.sh #!/bin/sh # Oh, oh, typo! It should be carlos not carlso dir=$(ls /home/carlso | sed -e "s,a,b,g") echo $? # We didn't notice though... [carlos@koi ~]$ ./test.sh ls: cannot access /home/carlso: No such file or directory 0 [carlos@koi ~]$
(3) Parse the fedpkg prep log output and verify that the expected tarball name was used.
else echo "Source prep failed." echo "Check the output above and fix things before committing." fi
echo "+ Done!"
Tada!
Cheers, Carlos.
On Mon, Jan 27, 2014 at 10:39:07AM -0500, Carlos O'Donell wrote:
Honestly I think you should check this into master as an example distribution script for RPM systems. That way others can look at what you've done without needing to go into a distribution specific branch.
It's glibc's responsibility to help downstream distributions use the project effectively.
Interesting. I could make that suggestion upstream once the script has a couple of weeks in rawhide and see what other maintainers think. I may have to make things a bit more generic, but that shouldn't be too much of a problem. However, I don't think there are a lot of distributions that ship glibc from master; only we are that brave ;)
I redid the script now, chucking away all of the `make dist` stuff since it made things unnecessarily complicated. Besides, we do a `git archive` anyway, so I figured I'll just do that straight away. I have obviously also incorporated changes you suggested in your review comments. How does this look for rawhide?
Siddhesh
#!/bin/sh # Given a git source repo, generate a tarball from the desired branch, modify # the spec file and upload it to lookaside cache if the tarball unpacks and # gets patched cleanly.
set -e
# We want to sync from master by default. Change this if you want to sync from # another branch. branch=master
# We can't do anything without an upstream repo if [ $# -ne 1 ]; then echo "Usage: $0 <path-to-upstream-repo>" 1>&2 exit 1 fi
upstream=$1
srcdir=$(git --git-dir=$upstream/.git describe $branch) cursrc=$(sed -ne 's/^%define glibcsrcdir (.*)/\1/p' glibc.spec)
# Upstream has not moved forward since the last sync. # TODO: Some time in the future, we might want to only sync when upstream has # advanced more than a certain number of commits, say, 42. if [ "$cursrc" = "$srcdir" ]; then echo "+ Already in sync with upstream." exit 0 fi
# Generate and gzip the tarball from the desired branch of the repository. echo "+ Generating tarball." git --git-dir="$upstream/.git" archive --prefix="$srcdir/" "$branch" \ > "$srcdir.tar" gzip -9 "$srcdir.tar" echo "+ Created $srcdir.tar.gz"
# Our changelog header cldate=$(date +'%a %b %d %Y') clname=$(git config --get user.name) clemail=$(git config --get user.email | sed 's/@/\@/')
# Getting our version and release number from the spec file. nv=$(perl -ne 's/^%define glibcversion (.+)/printf("%s-", $1)/e;' \ -e 's/^%define glibcrelease ([0-9]+).*/printf("%d\n", $1 + 1)/e;' \ glibc.spec)
# Our changelog entry. changelog="* $cldate $clname <$clemail> - $nv\n- Sync with upstream $branch\n"
# Change the glibcsrcdir variable, bump up the release number and add an extra # entry to the changelog. echo "+ Updating spec file." perl -pi \ -e "s/^(%define glibcsrcdir ).+/$1$srcdir/; s/^(%define glibcrelease )(\d+)/print($1); print($2 + 1);'';/e; s/^(%changelog)$/$1\n$changelog/" \ glibc.spec
echo "+ Testing if fedpkg prep works." tmpfile=$(mktemp fedpkg-prep.out-XXXX) set +e fedpkg prep > "$tmpfile" 2>&1 if [ $? -eq 0 ]; then # Remove mess created by fedpkg prep rm -f "$tmpfile" rm -rf "$srcdir" echo "+ Source prep is clean, so we're good to go." set -e fedpkg new-sources "$srcdir.tar.gz" git commit -a -m "Sync with upstream $branch" fedpkg push fedpkg build echo "+ Done!" else echo "+ Source prep failed." echo "+ Check the output in $tmpfile and fix things before committing." fi
On 01/28/2014 04:54 AM, Siddhesh Poyarekar wrote:
On Mon, Jan 27, 2014 at 10:39:07AM -0500, Carlos O'Donell wrote:
Honestly I think you should check this into master as an example distribution script for RPM systems. That way others can look at what you've done without needing to go into a distribution specific branch.
It's glibc's responsibility to help downstream distributions use the project effectively.
Interesting. I could make that suggestion upstream once the script has a couple of weeks in rawhide and see what other maintainers think. I may have to make things a bit more generic, but that shouldn't be too much of a problem. However, I don't think there are a lot of distributions that ship glibc from master; only we are that brave ;)
We are brave enough to put it into Rawhide. You then have to be brave enough to install Rawhide ;-)
I redid the script now, chucking away all of the `make dist` stuff since it made things unnecessarily complicated. Besides, we do a `git archive` anyway, so I figured I'll just do that straight away. I have obviously also incorporated changes you suggested in your review comments. How does this look for rawhide?
Almost there.
Don't disable -e, instead install a trap handler to execute else branch of the if statement.
#!/bin/sh # Given a git source repo, generate a tarball from the desired branch, modify # the spec file and upload it to lookaside cache if the tarball unpacks and # gets patched cleanly.
set -e
# We want to sync from master by default. Change this if you want to sync from # another branch. branch=master
# We can't do anything without an upstream repo if [ $# -ne 1 ]; then echo "Usage: $0 <path-to-upstream-repo>" 1>&2 exit 1 fi
upstream=$1
srcdir=$(git --git-dir=$upstream/.git describe $branch) cursrc=$(sed -ne 's/^%define glibcsrcdir (.*)/\1/p' glibc.spec)
# Upstream has not moved forward since the last sync. # TODO: Some time in the future, we might want to only sync when upstream has # advanced more than a certain number of commits, say, 42. if [ "$cursrc" = "$srcdir" ]; then echo "+ Already in sync with upstream." exit 0 fi
# Generate and gzip the tarball from the desired branch of the repository. echo "+ Generating tarball." git --git-dir="$upstream/.git" archive --prefix="$srcdir/" "$branch" \
"$srcdir.tar"
gzip -9 "$srcdir.tar" echo "+ Created $srcdir.tar.gz"
# Our changelog header cldate=$(date +'%a %b %d %Y') clname=$(git config --get user.name) clemail=$(git config --get user.email | sed 's/@/\@/')
# Getting our version and release number from the spec file. nv=$(perl -ne 's/^%define glibcversion (.+)/printf("%s-", $1)/e;' \ -e 's/^%define glibcrelease ([0-9]+).*/printf("%d\n", $1 + 1)/e;' \ glibc.spec)
# Our changelog entry. changelog="* $cldate $clname <$clemail> - $nv\n- Sync with upstream $branch\n"
# Change the glibcsrcdir variable, bump up the release number and add an extra # entry to the changelog. echo "+ Updating spec file." perl -pi \ -e "s/^(%define glibcsrcdir ).+/$1$srcdir/; s/^(%define glibcrelease )(\d+)/print($1); print($2 + 1);'';/e; s/^(%changelog)$/$1\n$changelog/" \ glibc.spec
echo "+ Testing if fedpkg prep works." tmpfile=$(mktemp fedpkg-prep.out-XXXX) set +e fedpkg prep > "$tmpfile" 2>&1 if [ $? -eq 0 ]; then # Remove mess created by fedpkg prep rm -f "$tmpfile" rm -rf "$srcdir" echo "+ Source prep is clean, so we're good to go." set -e fedpkg new-sources "$srcdir.tar.gz" git commit -a -m "Sync with upstream $branch" fedpkg push fedpkg build echo "+ Done!" else echo "+ Source prep failed." echo "+ Check the output in $tmpfile and fix things before committing." fi
Cheers, Carlos.
On Tue, Jan 28, 2014 at 10:51:16AM -0500, Carlos O'Donell wrote:
Don't disable -e, instead install a trap handler to execute else branch of the if statement.
Done. This is what I finally committed.
Siddhesh
diff --git a/sync-upstream.sh b/sync-upstream.sh new file mode 100755 index 0000000..4697706 --- /dev/null +++ b/sync-upstream.sh @@ -0,0 +1,97 @@ +#!/bin/sh +# Given a git source repo, generate a tarball from the desired branch, modify +# the spec file and upload it to lookaside cache if the tarball unpacks and +# gets patched cleanly. +# +# Usage: +# +# 1. Invoke the script as follows: +# +# ./sync-upstream.sh upstream-repo +# +# where upstream-repo is the path to the synced upstream git repo. +# +# 2. Watch the script run. If it proceeds to building the package, then +# everything seems good and you just need to test the build after it +# is complete. If it exits before the build (you'll know if you read +# the output of the script) then manual intervention is required to +# complete the sync. This will typically happen when a patch fails +# to apply on the new sources. + +set -e + +# We want to sync from master by default. Change this if you want to sync from +# another branch. +branch=master + +# We can't do anything without an upstream repo +if [ $# -ne 1 ]; then + echo "Usage: $0 <path-to-upstream-repo>" 1>&2 + exit 1 +fi + +upstream=$1 + +srcdir=$(git --git-dir=$upstream/.git describe $branch) +cursrc=$(sed -ne 's/^%define glibcsrcdir (.*)/\1/p' glibc.spec) + +# Upstream has not moved forward since the last sync. +# TODO: Some time in the future, we might want to only sync when upstream has +# advanced more than a certain number of commits, say, 42. +if [ "$cursrc" = "$srcdir" ]; then + echo "+ Already in sync with upstream." + exit 0 +fi + +# Generate and gzip the tarball from the desired branch of the repository. +echo "+ Generating tarball." +git --git-dir="$upstream/.git" archive --prefix="$srcdir/" "$branch" \ + > "$srcdir.tar" +gzip -9 "$srcdir.tar" +echo "+ Created $srcdir.tar.gz" + +# Our changelog header +cldate=$(date +'%a %b %d %Y') +clname=$(git config --get user.name) +clemail=$(git config --get user.email | sed 's/@/\@/') + +# Getting our version and release number from the spec file. +nv=$(perl -ne 's/^%define glibcversion (.+)/printf("%s-", $1)/e;' \ + -e 's/^%define glibcrelease ([0-9]+).*/printf("%d\n", $1 + 1)/e;' \ + glibc.spec) + +# Our changelog entry. +changelog="* $cldate $clname <$clemail> - $nv\n- Sync with upstream $branch\n" + +# Change the glibcsrcdir variable, bump up the release number and add an extra +# entry to the changelog. +echo "+ Updating spec file." +perl -pi \ + -e "s/^(%define glibcsrcdir ).+/$1$srcdir/; + s/^(%define glibcrelease )(\d+)/print($1); print($2 + 1);'';/e; + s/^(%changelog)$/$1\n$changelog/" \ + glibc.spec + +function prep_failed { + # fedpkg prep failed. + if [ $? -ne 0 ]; then + echo "+ Source prep failed." + echo "+ Check the output in $tmpfile and fix things before committing." + false + fi +} + +echo "+ Testing if fedpkg prep works." +tmpfile=$(mktemp fedpkg-prep.out-XXXX) + +trap prep_failed EXIT +fedpkg prep > "$tmpfile" 2>&1 +# Remove mess created by fedpkg prep +rm -f "$tmpfile" +rm -rf "$srcdir" +echo "+ Source prep is clean, so we're good to go." +fedpkg new-sources "$srcdir.tar.gz" +git commit -a -m "Sync with upstream $branch" +fedpkg push +fedpkg build +echo "+ Done!"
On 01/28/2014 11:58 PM, Siddhesh Poyarekar wrote:
On Tue, Jan 28, 2014 at 10:51:16AM -0500, Carlos O'Donell wrote:
Don't disable -e, instead install a trap handler to execute else branch of the if statement.
Done. This is what I finally committed.
Looks great. The trap handler makes the code more readable and clear, you now have only the successful flow handling.
Siddhesh
diff --git a/sync-upstream.sh b/sync-upstream.sh new file mode 100755 index 0000000..4697706 --- /dev/null +++ b/sync-upstream.sh @@ -0,0 +1,97 @@ +#!/bin/sh +# Given a git source repo, generate a tarball from the desired branch, modify +# the spec file and upload it to lookaside cache if the tarball unpacks and +# gets patched cleanly. +# +# Usage: +# +# 1. Invoke the script as follows: +# +# ./sync-upstream.sh upstream-repo +# +# where upstream-repo is the path to the synced upstream git repo. +# +# 2. Watch the script run. If it proceeds to building the package, then +# everything seems good and you just need to test the build after it +# is complete. If it exits before the build (you'll know if you read +# the output of the script) then manual intervention is required to +# complete the sync. This will typically happen when a patch fails +# to apply on the new sources.
+set -e
+# We want to sync from master by default. Change this if you want to sync from +# another branch. +branch=master
+# We can't do anything without an upstream repo +if [ $# -ne 1 ]; then
- echo "Usage: $0 <path-to-upstream-repo>" 1>&2
- exit 1
+fi
+upstream=$1
+srcdir=$(git --git-dir=$upstream/.git describe $branch) +cursrc=$(sed -ne 's/^%define glibcsrcdir (.*)/\1/p' glibc.spec)
+# Upstream has not moved forward since the last sync. +# TODO: Some time in the future, we might want to only sync when upstream has +# advanced more than a certain number of commits, say, 42. +if [ "$cursrc" = "$srcdir" ]; then
- echo "+ Already in sync with upstream."
- exit 0
+fi
+# Generate and gzip the tarball from the desired branch of the repository. +echo "+ Generating tarball." +git --git-dir="$upstream/.git" archive --prefix="$srcdir/" "$branch" \
"$srcdir.tar"+gzip -9 "$srcdir.tar" +echo "+ Created $srcdir.tar.gz"
+# Our changelog header +cldate=$(date +'%a %b %d %Y') +clname=$(git config --get user.name) +clemail=$(git config --get user.email | sed 's/@/\@/')
+# Getting our version and release number from the spec file. +nv=$(perl -ne 's/^%define glibcversion (.+)/printf("%s-", $1)/e;' \
-e 's/^%define glibcrelease ([0-9]+).*/printf("%d\n", $1 + 1)/e;' \
glibc.spec)
+# Our changelog entry. +changelog="* $cldate $clname <$clemail> - $nv\n- Sync with upstream $branch\n"
+# Change the glibcsrcdir variable, bump up the release number and add an extra +# entry to the changelog. +echo "+ Updating spec file." +perl -pi \
- -e "s/^(%define glibcsrcdir ).+/$1$srcdir/;
s/^(%define glibcrelease )(\d+)/print(\$1); print(\$2 + 1);'';/e;
s/^(%changelog)$/\$1\n$changelog/" \
- glibc.spec
+function prep_failed {
- # fedpkg prep failed.
- if [ $? -ne 0 ]; then
echo "+ Source prep failed."
echo "+ Check the output in $tmpfile and fix things before committing."
false
- fi
+}
+echo "+ Testing if fedpkg prep works." +tmpfile=$(mktemp fedpkg-prep.out-XXXX)
+trap prep_failed EXIT +fedpkg prep > "$tmpfile" 2>&1 +# Remove mess created by fedpkg prep +rm -f "$tmpfile" +rm -rf "$srcdir" +echo "+ Source prep is clean, so we're good to go." +fedpkg new-sources "$srcdir.tar.gz" +git commit -a -m "Sync with upstream $branch" +fedpkg push +fedpkg build +echo "+ Done!" _______________________________________________ glibc mailing list glibc@lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/glibc