/**
     * Runs Docker command using Docker CLI.
     *
     * @param cmd Command to be executed
     * @param logStdOut If true, propagate STDOUT to the build log
     * @param logStdErr If true, propagate STDERR to the build log
     * @return Execution result
     * @throws IOException Execution error
     * @throws InterruptedException The build has been interrupted
     */
    private @Nonnull Result executeCmd(@Nonnull String cmd, boolean logStdOut, boolean logStdErr)
        throws IOException, InterruptedException {
      ByteArrayOutputStream baosStdOut = new ByteArrayOutputStream();
      ByteArrayOutputStream baosStdErr = new ByteArrayOutputStream();
      OutputStream stdout =
          logStdOut ? new TeeOutputStream(listener.getLogger(), baosStdOut) : baosStdOut;
      OutputStream stderr =
          logStdErr ? new TeeOutputStream(listener.getLogger(), baosStdErr) : baosStdErr;

      // get Docker registry credentials
      KeyMaterial registryKey = getRegistry().newKeyMaterialFactory(build).materialize();
      // Docker server credentials. If server is null (right after upgrading) do not use credentials
      KeyMaterial serverKey =
          server == null ? null : server.newKeyMaterialFactory(build).materialize();

      logger.log(Level.FINER, "Executing: {0}", cmd);

      try {
        EnvVars env = new EnvVars();
        env.putAll(build.getEnvironment(listener));
        env.putAll(registryKey.env());
        if (serverKey != null) {
          env.putAll(serverKey.env());
        }

        boolean result =
            launcher
                    .launch()
                    .envs(env)
                    .pwd(build.getWorkspace())
                    .stdout(stdout)
                    .stderr(stderr)
                    .cmdAsSingleString(cmd)
                    .start()
                    .join()
                == 0;

        // capture the stdout so it can be parsed later on
        final String stdOutStr = DockerCLIHelper.getConsoleOutput(baosStdOut, logger);
        final String stdErrStr = DockerCLIHelper.getConsoleOutput(baosStdErr, logger);
        return new Result(result, stdOutStr, stdErrStr);

      } finally {
        registryKey.close();
        if (serverKey != null) {
          serverKey.close();
        }
      }
    }