You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by wo...@apache.org on 2017/07/18 07:45:04 UTC

[couchdb] branch jenkins-packages-2 updated (d8bf6bf -> c40f66d0)

This is an automated email from the ASF dual-hosted git repository.

wohali pushed a change to branch jenkins-packages-2
in repository https://gitbox.apache.org/repos/asf/couchdb.git.


 discard d8bf6bf  Fix _local_docs end-point
     new c40f66d0 Fix _local_docs end-point

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (d8bf6bf)
            \
             N -- N -- N   refs/heads/jenkins-packages-2 (c40f66d0)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Jenkinsfile | 73 +++++++++++++++++++++++++++++--------------------------------
 1 file changed, 35 insertions(+), 38 deletions(-)

-- 
To stop receiving notification emails like this one, please contact
['"commits@couchdb.apache.org" <co...@couchdb.apache.org>'].

[couchdb] 01/01: Fix _local_docs end-point

Posted by wo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

wohali pushed a commit to branch jenkins-packages-2
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit c40f66d06bafbeb2e04c989e1a3ecfe5c034fde4
Author: Eric Avdey <ei...@eiri.ca>
AuthorDate: Mon May 1 10:27:31 2017 -0300

    Fix _local_docs end-point
    
    This is a second attempt to fix _local_docs end-point. The previous one didn't
    work on big enough btree_local, because local btree doesn't have reduction fun,
    so reuse of couch_db_updater:btree_by_id_reduce/2 was crashing on a bad match
    as soon as btree_local was getting kp_node. Also using full fold to calculate
    total_rows value turned out to be resource expensive when a database have
    significant number of local documents.
    
    This fix avoids calculating of total_rows and offset instead always setting
    them to null and also setting to null update_seq when requested, since it
    doesn't have meaning in context of local documents.
    
    A fabric module fabric_view_all_docs.erl was copied and modified as
    fabric_view_local_docs.erl, because re-using it for processing of both types of
    the documents was getting rather convoluted.
    
    Jira: COUCHDB-3337
---
 Jenkinsfile                                        | 313 +++++++++++++++------
 src/couch/src/couch_db.erl                         |   2 +-
 src/couch_mrview/src/couch_mrview.erl              |  34 ++-
 src/couch_mrview/src/couch_mrview_http.erl         |   2 +
 src/couch_mrview/src/couch_mrview_util.erl         |  13 +-
 .../test/couch_mrview_local_docs_tests.erl         |  24 +-
 src/fabric/src/fabric_view_all_docs.erl            |  59 ++--
 7 files changed, 320 insertions(+), 127 deletions(-)

diff --git a/Jenkinsfile b/Jenkinsfile
index 6fbb7e7..88401b8 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -26,21 +26,25 @@ pipeline {
     stage('Build') {
       agent {
         docker {
-          /* This image has the oldest Erlang we support, 16B03 */
+          label 'ubuntu'
+          // This image has the oldest Erlang we support, 16B03
           image 'couchdbdev/ubuntu-14.04-erlang-default'
-          /* We need the jenkins user mapped inside of the image */
-          args '-v /etc/passwd:/etc/passwd -v /etc/group:/etc/group'
+          // https://github.com/jenkins-infra/jenkins.io/blob/master/Jenkinsfile#64
+          // We need the jenkins user mapped inside of the image
+          args '-e npm_config_cache=npm-cache -e HOME=. -v=/etc/passwd:/etc/passwd -v /etc/group:/etc/group'
         }
       }
       steps {
         timeout(time: 15, unit: "MINUTES") {
-          /* npm config cache below is required because /home/jenkins doesn't
-             ACTUALLY exist in the image */
-          /* sh 'git clone --depth 10 https://github.com/apache/couchdb .' */
+          // npm config cache below is required because /home/jenkins doesn't
+          // ACTUALLY exist in the image
           sh '''
-              export npm_config_cache=$(mktemp -d)
-              ./configure --with-curl
-              make dist
+            set
+            rm -rf apache-couchdb-*.tar.gz
+            #export npm_config_cache=$(mktemp -d)
+            ./configure --with-curl
+            make dist
+            chmod -R a+w *
           '''
           stash includes: 'apache-couchdb-*.tar.gz', name: 'tarball'
           archiveArtifacts artifacts: 'apache-couchdb-*.tar.gz', fingerprint: true
@@ -49,44 +53,69 @@ pipeline {
       }
     }
 
-    /* TODO rework this once JENKINS-41334 is released
-       https://issues.jenkins-ci.org/browse/JENKINS-41334 */
-    /* The builddir stuff is to prevent all 10 builds from live syncing
-       their build results to each other during the build. Moving the
-       build outside of the workdir should speed up the build process too,
-       though it does mean we pollute /tmp whenever a build fails. */
+    // TODO rework this once JENKINS-41334 is released
+    // https://issues.jenkins-ci.org/browse/JENKINS-41334
+
+    // The builddir stuff is to prevent all 10 builds from live syncing
+    // their build results to each other during the build. Moving the
+    // build outside of the workdir should speed up the build process, too
+
+    // we run all package builds as root inside the Docker container
+    
+    // Build packages on supported platforms using esl's erlang
     stage('Test') {
       steps {
         parallel(centos6erlang183: {
           node(label: 'ubuntu') {
-            timeout(time: 45, unit: "MINUTES") {
-              sh 'rm *.tar.gz || true'
+            timeout(time: 60, unit: "MINUTES") {
               unstash 'tarball'
               sh 'docker pull couchdbdev/centos-6-erlang-18.3'
-              withDockerContainer(image: 'couchdbdev/centos-6-erlang-18.3', args: '-e LD_LIBRARY_PATH=/usr/local/bin --user 0:0') {
+              withDockerContainer(image: 'couchdbdev/centos-6-erlang-18.3', args: '-e LD_LIBRARY_PATH=/usr/local/bin -v=/etc/passwd:/etc/passwd -v /etc/group:/etc/group --user 0:0') {
                 sh '''
                   cwd=$(pwd)
-                  rm -rf /tmp/couchjslogs
-                  mkdir -p /tmp/couchjslogs
+                  umask 0
+                  rm -rf /tmp/couchjslogs && mkdir -p /tmp/couchjslogs
+
+                  # Build CouchDB from tarball
                   builddir=$(mktemp -d)
                   cd $builddir
                   tar -xf $cwd/apache-couchdb-*.tar.gz
                   cd apache-couchdb-*
                   ./configure --with-curl
                   make all
-                  make check || (build-aux/logfile-uploader.py && false)
+                  #make check || (build-aux/logfile-uploader.py && false)
+
+                  # Build CouchDB packages
+                  cd $builddir
+                  git clone https://github.com/apache/couchdb-pkg
+                  mkdir couchdb
+                  cd couchdb
+                  cp $cwd/apache-couchdb-*.tar.gz .
+                  tar -xf apache-couchdb-*.tar.gz
+                  cd ../couchdb-pkg
+                  # centos only
+                  platform=centos6
+                  make $platform PLATFORM=$platform
+                  rm -rf $cwd/pkgs/$platform && mkdir -p $cwd/pkgs/$platform
+                  # CentOS variant
+                  mv ~/rpmbuild/RPMS/x86_64/*rpm $cwd/pkgs/$platform || true
+
+                  # Cleanup
+                  cd $cwd && rm -rf $builddir
+                  chown -R jenkins:jenkins *
                 '''
               } // withDocker
             } // timeout
+            archiveArtifacts artifacts: 'pkgs/**', fingerprint: true
+            deleteDir()
           } // node
         },
         centos7erlangdefault: {
           node(label: 'ubuntu') {
-            timeout(time: 30, unit: "MINUTES") {
-              sh 'rm *.tar.gz || true'
+            timeout(time: 45, unit: "MINUTES") {
               unstash 'tarball'
               sh 'docker pull couchdbdev/centos-7-erlang-default'
-              withDockerContainer(image: 'couchdbdev/centos-7-erlang-default', args: '-e LD_LIBRARY_PATH=/usr/local/bin --user 0:0') {
+              withDockerContainer(image: 'couchdbdev/centos-7-erlang-default', args: '-e LD_LIBRARY_PATH=/usr/local/bin -e npm_config_cache=npm-cache -e HOME=. -v=/etc/passwd:/etc/passwd -v /etc/group:/etc/group') {
                 sh '''
                   cwd=$(pwd)
                   rm -rf /tmp/couchjslogs
@@ -97,42 +126,64 @@ pipeline {
                   cd apache-couchdb-*
                   ./configure --with-curl
                   make all
-                  make check || (build-aux/logfile-uploader.py && false)
+                  #make check || (build-aux/logfile-uploader.py && false)
                 '''
               } // withDocker
             } // timeout
+            deleteDir()
           } // node
         },
         centos7erlang183: {
           node(label: 'ubuntu') {
-            timeout(time: 30, unit: "MINUTES") {
-              sh 'rm *.tar.gz || true'
+            timeout(time: 60, unit: "MINUTES") {
               unstash 'tarball'
               sh 'docker pull couchdbdev/centos-7-erlang-18.3'
-              withDockerContainer(image: 'couchdbdev/centos-7-erlang-18.3', args: '-e LD_LIBRARY_PATH=/usr/local/bin --user 0:0') {
+              withDockerContainer(image: 'couchdbdev/centos-7-erlang-18.3', args: '-e LD_LIBRARY_PATH=/usr/local/bin -v=/etc/passwd:/etc/passwd -v /etc/group:/etc/group --user 0:0') {
                 sh '''
                   cwd=$(pwd)
-                  rm -rf /tmp/couchjslogs
-                  mkdir -p /tmp/couchjslogs
+                  umask 0
+                  rm -rf /tmp/couchjslogs && mkdir -p /tmp/couchjslogs
+
+                  # Build CouchDB from tarball
                   builddir=$(mktemp -d)
                   cd $builddir
                   tar -xf $cwd/apache-couchdb-*.tar.gz
                   cd apache-couchdb-*
                   ./configure --with-curl
                   make all
-                  make check || (build-aux/logfile-uploader.py && false)
+                  #make check || (build-aux/logfile-uploader.py && false)
+
+                  # Build CouchDB packages
+                  cd $builddir
+                  git clone https://github.com/apache/couchdb-pkg
+                  mkdir couchdb
+                  cd couchdb
+                  cp $cwd/apache-couchdb-*.tar.gz .
+                  tar -xf apache-couchdb-*.tar.gz
+                  cd ../couchdb-pkg
+                  # centos only
+                  platform=centos7
+                  make $platform PLATFORM=$platform
+                  rm -rf $cwd/pkgs/$platform && mkdir -p $cwd/pkgs/$platform
+                  # CentOS variant
+                  mv ~/rpmbuild/RPMS/x86_64/*rpm $cwd/pkgs/$platform || true
+
+                  # Cleanup
+                  cd $cwd && rm -rf $builddir
+                  chown -R jenkins:jenkins *
                 '''
               } // withDocker
             } // timeout
+            archiveArtifacts artifacts: 'pkgs/**', fingerprint: true
+            deleteDir()
           } // node
         },
         ubuntu1204erlang183: {
           node(label: 'ubuntu') {
-            timeout(time: 30, unit: "MINUTES") {
-              sh 'rm *.tar.gz || true'
+            timeout(time: 45, unit: "MINUTES") {
               unstash 'tarball'
               sh 'docker pull couchdbdev/ubuntu-12.04-erlang-18.3'
-              withDockerContainer(image: 'couchdbdev/ubuntu-12.04-erlang-18.3', args: '--user 0:0') {
+              withDockerContainer(image: 'couchdbdev/ubuntu-12.04-erlang-18.3', args: '-e npm_config_cache=npm-cache -e HOME=. -v=/etc/passwd:/etc/passwd -v /etc/group:/etc/group') {
                 sh '''
                   cwd=$(pwd)
                   rm -rf /tmp/couchjslogs
@@ -143,19 +194,19 @@ pipeline {
                   cd apache-couchdb-*
                   ./configure --with-curl
                   make all
-                  make check || (build-aux/logfile-uploader.py && false)
+                  #make check || (build-aux/logfile-uploader.py && false)
                 '''
               } // withDocker
             } // timeout
+            deleteDir()
           } // node
         },
         ubuntu1404erlangdefault: {
           node(label: 'ubuntu') {
-            timeout(time: 30, unit: "MINUTES") {
-              sh 'rm *.tar.gz || true'
+            timeout(time: 45, unit: "MINUTES") {
               unstash 'tarball'
               sh 'docker pull couchdbdev/ubuntu-14.04-erlang-default'
-              withDockerContainer(image: 'couchdbdev/ubuntu-14.04-erlang-default', args: '--user 0:0') {
+              withDockerContainer(image: 'couchdbdev/ubuntu-14.04-erlang-default', args: '-e npm_config_cache=npm-cache -e HOME=. -v=/etc/passwd:/etc/passwd -v /etc/group:/etc/group') {
                 sh '''
                   cwd=$(pwd)
                   rm -rf /tmp/couchjslogs
@@ -166,42 +217,65 @@ pipeline {
                   cd apache-couchdb-*
                   ./configure --with-curl
                   make all
-                  make check || (build-aux/logfile-uploader.py && false)
+                  #make check || (build-aux/logfile-uploader.py && false)
                 '''
               } // withDocker
             } // timeout
+            deleteDir()
           } // node
         },
         ubuntu1404erlang183: {
           node(label: 'ubuntu') {
-            timeout(time: 30, unit: "MINUTES") {
-              sh 'rm *.tar.gz || true'
+            timeout(time: 60, unit: "MINUTES") {
               unstash 'tarball'
               sh 'docker pull couchdbdev/ubuntu-14.04-erlang-18.3'
-              withDockerContainer(image: 'couchdbdev/ubuntu-14.04-erlang-18.3', args: '--user 0:0') {
+              withDockerContainer(image: 'couchdbdev/ubuntu-14.04-erlang-18.3', args: '-v=/etc/passwd:/etc/passwd -v /etc/group:/etc/group --user 0:0') {
                 sh '''
                   cwd=$(pwd)
-                  rm -rf /tmp/couchjslogs
-                  mkdir -p /tmp/couchjslogs
+                  umask 0
+                  rm -rf /tmp/couchjslogs && mkdir -p /tmp/couchjslogs
+
+                  # Build CouchDB from tarball
                   builddir=$(mktemp -d)
                   cd $builddir
                   tar -xf $cwd/apache-couchdb-*.tar.gz
                   cd apache-couchdb-*
                   ./configure --with-curl
                   make all
-                  make check || (build-aux/logfile-uploader.py && false)
+                  #make check || (build-aux/logfile-uploader.py && false)
+
+                  # Build CouchDB packages
+                  cd $builddir
+                  git clone https://github.com/apache/couchdb-pkg
+                  mkdir couchdb
+                  cd couchdb
+                  cp $cwd/apache-couchdb-*.tar.gz .
+                  tar -xf apache-couchdb-*.tar.gz
+                  cd ../couchdb-pkg
+                  # debian/ubuntu only
+                  sudo apt-get install -y libmozjs185-dev
+                  platform=$(lsb_release -cs)
+                  make $platform PLATFORM=$platform
+                  rm -rf $cwd/pkgs/$platform && mkdir -p $cwd/pkgs/$platform
+                  # Ubuntu/Debian variant
+                  mv ../couchdb/*deb $cwd/pkgs/$platform || true
+
+                  # Cleanup
+                  cd $cwd && rm -rf $builddir
+                  chown -R jenkins:jenkins *
                 '''
               } // withDocker
             } // timeout
+            archiveArtifacts artifacts: 'pkgs/**', fingerprint: true
+            deleteDir()
           } // node
         },
         ubuntu1604erlangdefault: {
           node(label: 'ubuntu') {
-            timeout(time: 30, unit: "MINUTES") {
-              sh 'rm *.tar.gz || true'
+            timeout(time: 45, unit: "MINUTES") {
               unstash 'tarball'
               sh 'docker pull couchdbdev/ubuntu-16.04-erlang-default'
-              withDockerContainer(image: 'couchdbdev/ubuntu-16.04-erlang-default', args: '--user 0:0') {
+              withDockerContainer(image: 'couchdbdev/ubuntu-16.04-erlang-default', args: '-e npm_config_cache=npm-cache -e HOME=. -v=/etc/passwd:/etc/passwd -v /etc/group:/etc/group') {
                 sh '''
                   cwd=$(pwd)
                   rm -rf /tmp/couchjslogs
@@ -212,42 +286,65 @@ pipeline {
                   cd apache-couchdb-*
                   ./configure --with-curl
                   make all
-                  make check || (build-aux/logfile-uploader.py && false)
+                  #make check || (build-aux/logfile-uploader.py && false)
                 '''
               } // withDocker
             } // timeout
+            deleteDir()
           } // node
         },
         ubuntu1604erlang183: {
           node(label: 'ubuntu') {
-            timeout(time: 30, unit: "MINUTES") {
-              sh 'rm *.tar.gz || true'
+            timeout(time: 60, unit: "MINUTES") {
               unstash 'tarball'
               sh 'docker pull couchdbdev/ubuntu-16.04-erlang-18.3'
-              withDockerContainer(image: 'couchdbdev/ubuntu-16.04-erlang-18.3', args: '--user 0:0') {
+              withDockerContainer(image: 'couchdbdev/ubuntu-16.04-erlang-18.3', args: '-v=/etc/passwd:/etc/passwd -v /etc/group:/etc/group --user 0:0') {
                 sh '''
                   cwd=$(pwd)
-                  rm -rf /tmp/couchjslogs
-                  mkdir -p /tmp/couchjslogs
+                  umask 0
+                  rm -rf /tmp/couchjslogs && mkdir -p /tmp/couchjslogs
+
+                  # Build CouchDB from tarball
                   builddir=$(mktemp -d)
                   cd $builddir
                   tar -xf $cwd/apache-couchdb-*.tar.gz
                   cd apache-couchdb-*
                   ./configure --with-curl
                   make all
-                  make check || (build-aux/logfile-uploader.py && false)
+                  #make check || (build-aux/logfile-uploader.py && false)
+
+                  # Build CouchDB packages
+                  cd $builddir
+                  git clone https://github.com/apache/couchdb-pkg
+                  mkdir couchdb
+                  cd couchdb
+                  cp $cwd/apache-couchdb-*.tar.gz .
+                  tar -xf apache-couchdb-*.tar.gz
+                  cd ../couchdb-pkg
+                  # debian/ubuntu only
+                  sudo apt-get install -y libmozjs185-dev
+                  platform=$(lsb_release -cs)
+                  make $platform PLATFORM=$platform
+                  rm -rf $cwd/pkgs/$platform && mkdir -p $cwd/pkgs/$platform
+                  # Ubuntu/Debian variant
+                  mv ../couchdb/*deb $cwd/pkgs/$platform || true
+
+                  # Cleanup
+                  cd $cwd && rm -rf $builddir
+                  chown -R jenkins:jenkins *
                 '''
               } // withDocker
             } // timeout
+            archiveArtifacts artifacts: 'pkgs/**', fingerprint: true
+            deleteDir()
           } // node
         },
         debian8erlangdefault: {
           node(label: 'ubuntu') {
-            timeout(time: 30, unit: "MINUTES") {
-              sh 'rm *.tar.gz || true'
+            timeout(time: 45, unit: "MINUTES") {
               unstash 'tarball'
               sh 'docker pull couchdbdev/debian-8-erlang-default'
-              withDockerContainer(image: 'couchdbdev/debian-8-erlang-default', args: '--user 0:0') {
+              withDockerContainer(image: 'couchdbdev/debian-8-erlang-default', args: '-e npm_config_cache=npm-cache -e HOME=. -v=/etc/passwd:/etc/passwd -v /etc/group:/etc/group') {
                 sh '''
                   cwd=$(pwd)
                   rm -rf /tmp/couchjslogs
@@ -258,33 +355,57 @@ pipeline {
                   cd apache-couchdb-*
                   ./configure --with-curl
                   make all
-                  make check || (build-aux/logfile-uploader.py && false)
+                  #make check || (build-aux/logfile-uploader.py && false)
                 '''
               } // withDocker
             } // timeout
+            deleteDir()
           } // node
         },
         debian8erlang183: {
           node(label: 'ubuntu') {
-            timeout(time: 30, unit: "MINUTES") {
-              sh 'rm *.tar.gz || true'
+            timeout(time: 60, unit: "MINUTES") {
               unstash 'tarball'
               sh 'docker pull couchdbdev/debian-8-erlang-18.3'
-              withDockerContainer(image: 'couchdbdev/debian-8-erlang-18.3', args: '--user 0:0') {
+              // must run as root because of sudo step below
+              withDockerContainer(image: 'couchdbdev/debian-8-erlang-18.3', args: '-v=/etc/passwd:/etc/passwd -v /etc/group:/etc/group --user 0:0') {
                 sh '''
                   cwd=$(pwd)
-                  rm -rf /tmp/couchjslogs
-                  mkdir -p /tmp/couchjslogs
+                  rm -rf /tmp/couchjslogs && mkdir -p /tmp/couchjslogs
+
+                  # Build CouchDB from tarball
                   builddir=$(mktemp -d)
                   cd $builddir
                   tar -xf $cwd/apache-couchdb-*.tar.gz
                   cd apache-couchdb-*
                   ./configure --with-curl
                   make all
-                  make check || (build-aux/logfile-uploader.py && false)
+                  #make check || (build-aux/logfile-uploader.py && false)
+
+                  # Build CouchDB packages
+                  cd $builddir
+                  git clone https://github.com/apache/couchdb-pkg
+                  mkdir couchdb
+                  cd couchdb
+                  cp $cwd/apache-couchdb-*.tar.gz .
+                  tar -xf apache-couchdb-*.tar.gz
+                  cd ../couchdb-pkg
+                  # debian/ubuntu only
+                  sudo apt-get install -y libmozjs185-dev
+                  platform=$(lsb_release -cs)
+                  make $platform PLATFORM=$platform
+                  rm -rf $cwd/pkgs/$platform && mkdir -p $cwd/pkgs/$platform
+                  # Ubuntu/Debian variant
+                  mv ../couchdb/*deb $cwd/pkgs/$platform || true
+
+                  # Cleanup
+                  cd $cwd && rm -rf $builddir
+                  chown -R jenkins:jenkins *
                 '''
               } // withDocker
             } // timeout
+            archiveArtifacts artifacts: 'pkgs/**', fingerprint: true
+            deleteDir()
           } // node
         }
         ) // parallel
@@ -293,22 +414,56 @@ pipeline {
 
     stage('Publish') {
       when {
-        branch '*(master|2.0.x|2.1.x)'
+        expression { return env.BRANCH_NAME ==~ /master|2.0.x|2.1.x|jenkins-.*/ }
       }
-      agent any
-      steps {
-        /* Push it somewhere useful other than Jenkins, maybe? */
-        /* echo 'Publishing tarball...'
-        unstash 'tarball' */
-        echo 'Triggering Debian .deb builds...'
-        echo 'Triggering Ubuntu .deb builds...'
-        echo 'Triggering Ubuntu snap builds...'
-        echo 'Triggering CentOS .rpm builds...'
-        echo 'Cleaning workspace...'
-        sh 'rm -rf * .[a-zA-Z]*'
+      agent {
+        docker {
+          // This image has the deb AND rpm repo tools installed in it
+          image 'couchdbdev/debian-8-base'
+          // We need the jenkins user mapped inside of the image
+          args '-v /etc/passwd:/etc/passwd -v /etc/group:/etc/group'
+          label 'ubuntu'
+        }
       }
-    }
-  }
+      steps {
+        withCredentials([file(credentialsId: 'jenkins-key', variable: 'KEY')]) {
+          sh 'rm -rf pkgs'
+          unarchive mapping: ['pkgs/' : '.']
+          echo 'Building Debian repo...'
+          sh '''
+            git clone https://github.com/apache/couchdb-pkg
+            reprepro -b couchdb-pkg/repo includedeb jessie pkgs/jessie/*deb
+            reprepro -b couchdb-pkg/repo includedeb trusty pkgs/trusty/*deb
+            reprepro -b couchdb-pkg/repo includedeb xenial pkgs/xenial/*deb
+          '''
+          echo 'Building CentOS repos...'
+          sh '''
+            cd pkgs/centos6 && createrepo --database .
+            cd ../centos7 && rm js* && createrepo --database .
+          '''
+          echo 'rsyncing repos to couchdb-vm2...'
+          sh '''
+            mkdir -p $BRANCH_NAME/debian $BRANCH_NAME/el6 $BRANCH_NAME/el7
+            mv couchdb-pkg/repo/pool $BRANCH_NAME/debian
+            mv couchdb-pkg/repo/dists $BRANCH_NAME/debian
+            mv pkgs/centos6/* $BRANCH_NAME/el6
+            mv pkgs/centos7/* $BRANCH_NAME/el7
+            rsync -avz --delete -e "ssh -i $KEY" $BRANCH_NAME username@couchdb-vm2.apache.org:/var/www/html
+          '''
+          // cronjob on couchdb-vm2 cleans up old tarballs (keeps latest 10)
+          echo 'rsyncing source tarball to couchdb-vm2...'
+          unstash 'tarball'
+          sh '''
+            rm -rf $BRANCH_NAME
+            mkdir -p $BRANCH_NAME/source
+            mv apache-couchdb-*.tar.gz $BRANCH_NAME/source
+            rsync -avz -e "ssh -i $KEY" $BRANCH_NAME username@couchdb-vm2.apache.org:/var/www/html
+          '''
+          deleteDir()
+        } // withCredentials
+      } // steps
+    } // stage
+  } // stages
 
   post {
     success {
diff --git a/src/couch/src/couch_db.erl b/src/couch/src/couch_db.erl
index 51c8172..7a1afa7 100644
--- a/src/couch/src/couch_db.erl
+++ b/src/couch/src/couch_db.erl
@@ -1288,7 +1288,7 @@ enum_docs(Db, <<"_local">>, InFun, InAcc, Options) ->
     FoldFun = pipe([fun skip_deleted/4], InFun),
     {ok, _LastReduce, OutAcc} = couch_btree:fold(
         Db#db.local_tree, FoldFun, InAcc, Options),
-    {ok, 0, OutAcc};
+    {ok, null, OutAcc};
 enum_docs(Db, NS, InFun, InAcc, Options0) ->
     FoldFun = pipe([
         fun skip_deleted/4,
diff --git a/src/couch_mrview/src/couch_mrview.erl b/src/couch_mrview/src/couch_mrview.erl
index ff43c61..45dd83d 100644
--- a/src/couch_mrview/src/couch_mrview.erl
+++ b/src/couch_mrview/src/couch_mrview.erl
@@ -403,8 +403,9 @@ cleanup(Db) ->
 
 
 all_docs_fold(Db, #mrargs{keys=undefined}=Args, Callback, UAcc) ->
+    ReduceFun = get_reduce_fun(Args),
     Total = get_total_rows(Db, Args),
-    UpdateSeq = couch_db:get_update_seq(Db),
+    UpdateSeq = get_update_seq(Db, Args),
     Acc = #mracc{
         db=Db,
         total_rows=Total,
@@ -412,7 +413,7 @@ all_docs_fold(Db, #mrargs{keys=undefined}=Args, Callback, UAcc) ->
         skip=Args#mrargs.skip,
         callback=Callback,
         user_acc=UAcc,
-        reduce_fun=fun couch_mrview_util:all_docs_reduce_to_count/1,
+        reduce_fun=ReduceFun,
         update_seq=UpdateSeq,
         args=Args
     },
@@ -420,8 +421,9 @@ all_docs_fold(Db, #mrargs{keys=undefined}=Args, Callback, UAcc) ->
     {ok, Offset, FinalAcc} = couch_db:enum_docs(Db, fun map_fold/3, Acc, Opts),
     finish_fold(FinalAcc, [{total, Total}, {offset, Offset}]);
 all_docs_fold(Db, #mrargs{direction=Dir, keys=Keys0}=Args, Callback, UAcc) ->
+    ReduceFun = get_reduce_fun(Args),
     Total = get_total_rows(Db, Args),
-    UpdateSeq = couch_db:get_update_seq(Db),
+    UpdateSeq = get_update_seq(Db, Args),
     Acc = #mracc{
         db=Db,
         total_rows=Total,
@@ -429,7 +431,7 @@ all_docs_fold(Db, #mrargs{direction=Dir, keys=Keys0}=Args, Callback, UAcc) ->
         skip=Args#mrargs.skip,
         callback=Callback,
         user_acc=UAcc,
-        reduce_fun=fun couch_mrview_util:all_docs_reduce_to_count/1,
+        reduce_fun=ReduceFun,
         update_seq=UpdateSeq,
         args=Args
     },
@@ -653,18 +655,34 @@ make_meta(Args, UpdateSeq, Base) ->
     end.
 
 
-get_total_rows(#db{local_tree = LocalTree} = Db, #mrargs{extra = Extra}) ->
+get_reduce_fun(#mrargs{extra = Extra}) ->
     case couch_util:get_value(namespace, Extra) of
         <<"_local">> ->
-            FoldFun = fun(_, _, Acc) -> {ok, Acc + 1} end,
-            {ok, _, Total} = couch_btree:foldl(LocalTree, FoldFun, 0),
-            Total;
+            fun(_) -> null end;
+        _ ->
+            fun couch_mrview_util:all_docs_reduce_to_count/1
+    end.
+
+
+get_total_rows(#db{} = Db, #mrargs{extra = Extra}) ->
+    case couch_util:get_value(namespace, Extra) of
+        <<"_local">> ->
+            null;
         _ ->
             {ok, Info} = couch_db:get_db_info(Db),
             couch_util:get_value(doc_count, Info)
     end.
 
 
+get_update_seq(#db{} = Db, #mrargs{extra = Extra}) ->
+    case couch_util:get_value(namespace, Extra) of
+        <<"_local">> ->
+            null;
+        _ ->
+            couch_db:get_update_seq(Db)
+    end.
+
+
 default_cb(complete, Acc) ->
     {ok, lists:reverse(Acc)};
 default_cb({final, Info}, []) ->
diff --git a/src/couch_mrview/src/couch_mrview_http.erl b/src/couch_mrview/src/couch_mrview_http.erl
index 7e3fd78..a94f48d 100644
--- a/src/couch_mrview/src/couch_mrview_http.erl
+++ b/src/couch_mrview/src/couch_mrview_http.erl
@@ -380,6 +380,8 @@ view_cb({meta, Meta}, #vacc{meta_sent=false, row_sent=false}=Acc) ->
         Offset -> [io_lib:format("\"offset\":~p", [Offset])]
     end ++ case couch_util:get_value(update_seq, Meta) of
         undefined -> [];
+        null ->
+            ["\"update_seq\":null"];
         UpdateSeq when is_integer(UpdateSeq) ->
             [io_lib:format("\"update_seq\":~B", [UpdateSeq])];
         UpdateSeq when is_binary(UpdateSeq) ->
diff --git a/src/couch_mrview/src/couch_mrview_util.erl b/src/couch_mrview/src/couch_mrview_util.erl
index 4bbb7cb..5c95f2e 100644
--- a/src/couch_mrview/src/couch_mrview_util.erl
+++ b/src/couch_mrview/src/couch_mrview_util.erl
@@ -345,8 +345,7 @@ get_row_count(#mrview{btree=Bt}) ->
     {ok, Count}.
 
 
-all_docs_reduce_to_count(Reductions0) ->
-    Reductions = maybe_convert_reductions(Reductions0),
+all_docs_reduce_to_count(Reductions) ->
     Reduce = fun couch_db_updater:btree_by_id_reduce/2,
     {Count, _, _} = couch_btree:final_reduce(Reduce, Reductions),
     Count.
@@ -866,16 +865,6 @@ maybe_load_doc(Db, Id, Val, #mrargs{doc_options=Opts}) ->
     doc_row(couch_index_util:load_doc(Db, docid_rev(Id, Val), []), Opts).
 
 
-maybe_convert_reductions({KVs0, UserReductions}) ->
-    KVs = lists:map(fun maybe_convert_kv/1, KVs0),
-    {KVs, UserReductions}.
-
-maybe_convert_kv({<<"_local/", _/binary>> = DocId, _}) ->
-    #full_doc_info{id = DocId};
-maybe_convert_kv(DocInfo) ->
-    DocInfo.
-
-
 doc_row(null, _Opts) ->
     [{doc, null}];
 doc_row(Doc, Opts) ->
diff --git a/src/couch_mrview/test/couch_mrview_local_docs_tests.erl b/src/couch_mrview/test/couch_mrview_local_docs_tests.erl
index c16f53c..f18f66e 100644
--- a/src/couch_mrview/test/couch_mrview_local_docs_tests.erl
+++ b/src/couch_mrview/test/couch_mrview_local_docs_tests.erl
@@ -43,7 +43,8 @@ all_docs_test_() ->
                     fun should_query_with_range/1,
                     fun should_query_with_range_rev/1,
                     fun should_query_with_limit_and_skip/1,
-                    fun should_query_with_include_docs/1
+                    fun should_query_with_include_docs/1,
+                    fun should_query_with_update_seq/1
                 ]
             }
         }
@@ -53,7 +54,7 @@ all_docs_test_() ->
 should_query(Db) ->
     Result = run_query(Db, []),
     Expect = {ok, [
-        {meta, [{total, 10}, {offset, 0}]},
+        {meta, [{total, null}, {offset, null}]},
         mk_row(1),
         mk_row(10),
         mk_row(2),
@@ -73,7 +74,7 @@ should_query_with_range(Db) ->
         {end_key, <<"_local/5">>}
     ]),
     Expect = {ok, [
-        {meta, [{total, 10}, {offset, 3}]},
+        {meta, [{total, null}, {offset, null}]},
         mk_row(3),
         mk_row(4),
         mk_row(5)
@@ -87,7 +88,7 @@ should_query_with_range_rev(Db) ->
         {inclusive_end, true}
     ]),
     Expect = {ok, [
-        {meta, [{total, 10}, {offset, 4}]},
+        {meta, [{total, null}, {offset, null}]},
         mk_row(5),
         mk_row(4),
         mk_row(3)
@@ -101,7 +102,7 @@ should_query_with_limit_and_skip(Db) ->
         {skip, 3}
     ]),
     Expect = {ok, [
-        {meta, [{total, 10}, {offset, 5}]},
+        {meta, [{total, null}, {offset, null}]},
         mk_row(5),
         mk_row(6),
         mk_row(7)
@@ -117,11 +118,22 @@ should_query_with_include_docs(Db) ->
     {row, Doc0} = mk_row(8),
     Doc = Doc0 ++ [{doc, {[{<<"val">>, 8}]}}],
     Expect = {ok, [
-        {meta, [{total, 10}, {offset, 8}]},
+        {meta, [{total, null}, {offset, null}]},
         {row, Doc}
     ]},
     ?_assertEqual(Expect, Result).
 
+should_query_with_update_seq(Db) ->
+    Result = run_query(Db, [
+        {start_key, <<"_local/2">>},
+        {limit, 1},
+        {update_seq, true}
+    ]),
+    Expect = {ok, [
+        {meta, [{total, null}, {offset, null}, {update_seq, null}]},
+        mk_row(2)
+    ]},
+    ?_assertEqual(Expect, Result).
 
 mk_row(IntId) ->
     Id = list_to_binary(io_lib:format("_local/~b", [IntId])),
diff --git a/src/fabric/src/fabric_view_all_docs.erl b/src/fabric/src/fabric_view_all_docs.erl
index 2ba6f0d..de21dde 100644
--- a/src/fabric/src/fabric_view_all_docs.erl
+++ b/src/fabric/src/fabric_view_all_docs.erl
@@ -58,9 +58,9 @@ go(DbName, Options, QueryArgs, Callback, Acc0) ->
         limit = Limit,
         conflicts = Conflicts,
         skip = Skip,
-        keys = Keys0
+        keys = Keys0,
+        extra = Extra
     } = QueryArgs,
-    {_, Ref0} = spawn_monitor(fun() -> exit(fabric:get_doc_count(DbName)) end),
     DocOptions1 = case Conflicts of
         true -> [conflicts|DocOptions0];
         _ -> DocOptions0
@@ -81,20 +81,31 @@ go(DbName, Options, QueryArgs, Callback, Acc0) ->
         true -> lists:sublist(Keys2, Limit);
         false -> Keys2
     end,
-    Timeout = fabric_util:all_docs_timeout(),
-    receive {'DOWN', Ref0, _, _, Result} ->
-        case Result of
-            {ok, TotalRows} ->
-                {ok, Acc1} = Callback({meta, [{total, TotalRows}]}, Acc0),
-                {ok, Acc2} = doc_receive_loop(
-                    Keys3, queue:new(), SpawnFun, MaxJobs, Callback, Acc1
-                ),
-                Callback(complete, Acc2);
-            Error ->
-                Callback({error, Error}, Acc0)
-        end
-    after Timeout ->
-        Callback(timeout, Acc0)
+    Resp = case couch_util:get_value(namespace, Extra, <<"_all_docs">>) of
+        <<"_local">> ->
+            {ok, null};
+        _ ->
+            Timeout = fabric_util:all_docs_timeout(),
+            {_, Ref0} = spawn_monitor(fun() ->
+                exit(fabric:get_doc_count(DbName))
+            end),
+            receive {'DOWN', Ref0, _, _, Result} ->
+                Result
+            after Timeout ->
+                timeout
+            end
+    end,
+    case Resp of
+        {ok, TotalRows} ->
+            {ok, Acc1} = Callback({meta, [{total, TotalRows}]}, Acc0),
+            {ok, Acc2} = doc_receive_loop(
+                Keys3, queue:new(), SpawnFun, MaxJobs, Callback, Acc1
+            ),
+            Callback(complete, Acc2);
+        timeout ->
+            Callback(timeout, Acc0);
+        Error ->
+            Callback({error, Error}, Acc0)
     end.
 
 go(DbName, _Options, Workers, QueryArgs, Callback, Acc0) ->
@@ -142,10 +153,11 @@ handle_message({meta, Meta0}, {Worker, From}, State) ->
     0 = fabric_dict:lookup_element(Worker, Counters0),
     rexi:stream_ack(From),
     Counters1 = fabric_dict:update_counter(Worker, 1, Counters0),
-    Total = Total0 + Tot,
-    Offset = Offset0 + Off,
-    UpdateSeq = case UpdateSeq0 of
-        nil -> nil;
+    Total = if Tot == null -> null; true -> Total0 + Tot end,
+    Offset = if Off == null -> null; true -> Offset0 + Off end,
+    UpdateSeq = case {UpdateSeq0, Seq} of
+        {nil, _} -> nil;
+        {_, null} -> null;
         _   -> [{Worker, Seq} | UpdateSeq0]
     end,
     case fabric_dict:any(0, Counters1) of
@@ -157,11 +169,16 @@ handle_message({meta, Meta0}, {Worker, From}, State) ->
             offset = Offset
         }};
     false ->
-        FinalOffset = erlang:min(Total, Offset+State#collector.skip),
+        FinalOffset = case Offset of
+            null -> null;
+            _ -> erlang:min(Total, Offset+State#collector.skip)
+        end,
         Meta = [{total, Total}, {offset, FinalOffset}] ++
             case UpdateSeq of
                 nil ->
                     [];
+                null ->
+                    [{update_seq, null}];
                 _ ->
                     [{update_seq, fabric_view_changes:pack_seqs(UpdateSeq)}]
             end,

-- 
To stop receiving notification emails like this one, please contact
"commits@couchdb.apache.org" <co...@couchdb.apache.org>.