docs: function ping(opts, cb) {
      assert.func(cb, 'cb');
      assert.object(opts, 'opts');
      assert.ok(opts.index || opts.indexName,
          'opts.index or opts.indexName is required');
      assert.optionalObject(opts.log, 'opts.log');
      // HTTP client basic options:
      assert.optionalBool(opts.insecure, 'opts.insecure');
      assert.optionalBool(opts.rejectUnauthorized, 'opts.rejectUnauthorized');
      assert.optionalString(opts.userAgent, 'opts.userAgent');
      assert.optionalObject(opts.agent, 'opts.agent');
      // assert.optional object or bool(opts.proxy, 'opts.proxy');
  
      var index = opts.index || opts.indexName;
      if (typeof (index) === 'string') {
          try {
              index = common.parseIndex(index);
          } catch (indexNameErr) {
              cb(indexNameErr);
              return;
          }
      } else {
          assert.object(index, 'opts.index');
      }
  
      var log = _createLogger(opts.log);
      log.trace({index: index, scope: opts.scope, insecure: opts.insecure},
          'ping');
  
      /*
       * We have to special case usage of the "official" docker.io to
       *      https://registry-1.docker.io
       * because:
       *      GET /v2/ HTTP/1.1
       *      Host: index.docker.io
       *
       *      HTTP/1.1 301 Moved Permanently
       *      location: https://registry.hub.docker.com/v2/
       * and:
       *      $ curl -i https://registry.hub.docker.com/v2/
       *      HTTP/1.1 404 NOT FOUND
       */
      var registryUrl;
      if (index.official) {
          registryUrl = DEFAULT_V2_REGISTRY;
      } else {
          registryUrl = common.urlFromIndex(index);
      }
  
      /*
       * We allow either opts.rejectUnauthorized (for passed in http client
       * options where `insecure` -> `rejectUnauthorized` translation has
       * already been done) or opts.insecure (this module's chosen name
       * for this thing).
       */
      var rejectUnauthorized;
      if (opts.insecure !== undefined && opts.rejectUnauthorized !== undefined) {
          throw new assert.AssertionError(
              'cannot set both opts.insecure and opts.rejectUnauthorized');
      } else if (opts.insecure !== undefined) {
          rejectUnauthorized = !opts.insecure;
      } else if (opts.rejectUnauthorized !== undefined) {
          rejectUnauthorized = opts.rejectUnauthorized;
      }
  
      var client = new DockerJsonClient({
          url: registryUrl,
          log: opts.log,
          userAgent: opts.userAgent || common.DEFAULT_USERAGENT,
          rejectUnauthorized: rejectUnauthorized,
          agent: opts.agent,
          proxy: opts.proxy
      });
  
      client.get({
          path: '/v2/',
          // Ping should be fast. We don't want 15s of retrying.
          retry: false,
          connectTimeout: 10000
      }, function _afterPing(err, req, res, body) {
          client.close();
          cb(err, body, res, req);
      });
  }