quarto-dev / quarto-cli

Open-source scientific and technical publishing system built on Pandoc.
https://quarto.org
Other
3.97k stars 327 forks source link

Quarto check fails and render to HTML fails in secured enterprise environment #6651

Open cs-res-pub-ser-st opened 1 year ago

cs-res-pub-ser-st commented 1 year ago

Bug description

The quarto check commands fails with ERROR: Theme compilation failed: with blank error message, making it difficult to further diagnose the issue. Render to HTML also fails with ERROR: Theme compilation failed: with blank error message.

RStudio was installed in a secured enterprise environment (and cannot be installed otherwise). I suspect that some step(s) during Quarto installation silently failed in this environment.

Note that most features of Quarto still work. Specifically, rendering to both Word and PowerPoint behave as expected in Quarto v1.3 (with current Word/Quarto issues related to specific rendering behavior and cross-references that are targeted to be resolved in Quarto v1.4). The glaring missing functionality is HTML rendering, which fails even with the Quarto default document.

Steps to reproduce

1) Load recent version of RStudio installed in secured enterprise environment 2) Initiate quarto check in the Terminal tab

[Fails at this point with ERROR: Theme file compilation failed: with blank error message.]

3) Create new Quarto project in RStudio 4) Add format: html to Quarto document options 5) Try to render

[Fails at this point with ERROR: Theme file compilation failed: with blank error message.]

The failure to render to HTML occurs even with the default Quarto document:

---
title: "Quarto_test_HTML"
format: html
---

## Quarto

Quarto enables you to weave together content and executable code into a finished document. To learn more about Quarto see <https://quarto.org>.

```{r}
1 + 1

### Expected behavior

Should be able to successfully run `quarto check` and render to HTML using the Quarto default document.

### Actual behavior

**Quarto check**
Quarto fails the check with the following Terminal output:

```bash
$ quarto check

[>] Checking versions of quarto binary dependencies...
      Pandoc version 3.1.1: OK
ERROR: Theme file compilation failed:

Error: Theme file compilation failed:

    at dartCommand (file:///C:/Program%20Files/RStudio/resources/app/bin/quarto/bin/quarto.js:59892:15)
    at async checkVersions (file:///C:/Program%20Files/RStudio/resources/app/bin/quarto/bin/quarto.js:104031:26)
    at async check (file:///C:/Program%20Files/RStudio/resources/app/bin/quarto/bin/quarto.js:103988:13)
    at async Command.fn (file:///C:/Program%20Files/RStudio/resources/app/bin/quarto/bin/quarto.js:104211:5)
    at async Command.execute (file:///C:/Program%20Files/RStudio/resources/app/bin/quarto/bin/quarto.js:8437:13)
    at async quarto (file:///C:/Program%20Files/RStudio/resources/app/bin/quarto/bin/quarto.js:127539:5)
    at async file:///C:/Program%20Files/RStudio/resources/app/bin/quarto/bin/quarto.js:127557:9

Quarto rendering to HTML Quarto fails to render to HTML, with the following Background Jobs output:

processing file: Quarto_test_HTML.qmd
1/3                  
2/3 [unnamed-chunk-1]
3/3                  
output file: Quarto_test_HTML.knit.md

ERROR: Theme file compilation failed:

Error: Theme file compilation failed:

    at dartCommand (file:///C:/PROGRA~1/RStudio/RESOUR~1/app/bin/quarto/bin/quarto.js:59892:15)
    at async dartCompile (file:///C:/PROGRA~1/RStudio/RESOUR~1/app/bin/quarto/bin/quarto.js:59854:5)
    at async compileWithCache (file:///C:/PROGRA~1/RStudio/RESOUR~1/app/bin/quarto/bin/quarto.js:60082:17)
    at async compileSass (file:///C:/PROGRA~1/RStudio/RESOUR~1/app/bin/quarto/bin/quarto.js:59944:12)
    at async resolveSassBundles (file:///C:/PROGRA~1/RStudio/RESOUR~1/app/bin/quarto/bin/quarto.js:76331:27)
    at async resolveExtras (file:///C:/PROGRA~1/RStudio/RESOUR~1/app/bin/quarto/bin/quarto.js:80426:18)
    at async runPandoc (file:///C:/PROGRA~1/RStudio/RESOUR~1/app/bin/quarto/bin/quarto.js:79981:24)
    at async renderPandoc (file:///C:/PROGRA~1/RStudio/RESOUR~1/app/bin/quarto/bin/quarto.js:81042:26)
    at async Object.onRender (file:///C:/PROGRA~1/RStudio/RESOUR~1/app/bin/quarto/bin/quarto.js:86671:36)
    at async renderFiles (file:///C:/PROGRA~1/RStudio/RESOUR~1/app/bin/quarto/bin/quarto.js:86634:25)

Your environment

Quarto check output

$ quarto check

[>] Checking versions of quarto binary dependencies...
      Pandoc version 3.1.1: OK
ERROR: Theme file compilation failed:

Error: Theme file compilation failed:

    at dartCommand (file:///C:/Program%20Files/RStudio/resources/app/bin/quarto/bin/quarto.js:59892:15)
    at async checkVersions (file:///C:/Program%20Files/RStudio/resources/app/bin/quarto/bin/quarto.js:104031:26)
    at async check (file:///C:/Program%20Files/RStudio/resources/app/bin/quarto/bin/quarto.js:103988:13)
    at async Command.fn (file:///C:/Program%20Files/RStudio/resources/app/bin/quarto/bin/quarto.js:104211:5)
    at async Command.execute (file:///C:/Program%20Files/RStudio/resources/app/bin/quarto/bin/quarto.js:8437:13)
    at async quarto (file:///C:/Program%20Files/RStudio/resources/app/bin/quarto/bin/quarto.js:127539:5)
    at async file:///C:/Program%20Files/RStudio/resources/app/bin/quarto/bin/quarto.js:127557:9

Edited to fix some a typo and a formatting issue, but no changes to anything substantial

mcanouil commented 1 year ago
  1. Could you check that you don't have a _quarto.yml somewhere in the project directory or its parent?
  2. Could you test to use Quarto from the command line?
cderv commented 1 year ago
Error: Theme file compilation failed:

   at dartCommand (file:///C:/Program%20Files/RStudio/resources/app/bin/quarto/bin/quarto.js:59892:15)
   at async checkVersions (file:///C:/Program%20Files/RStudio/resources/app/bin/quarto/bin/quarto.js:104031:26)

This issue is usually related to SASS compilation using dart-saas binary that Quarto is doing for HTML theming (to build .css from .scss file). Here as you mentioned quarto check issue, this is even an error while trying to run the dart binary to get its version. To me this looks like an issue while running the file.

As you mentioned you are in a corporate environment, you may want to check any software scanning or antivirus scanning that would wrongly prevent dart binary from running.

FYI the program that is ran is at bin\tools\dart-sass\sass.bat from your Quarto install directory. So I presume C:/PROGRA~1/RStudio/RESOUR~1/app/bin/quarto/bin/tools/dart-sass/sass.bat in your case. Maybe .bat file are blocked in your environment ?

This happens here https://github.com/quarto-dev/quarto-cli/blob/72c30a8317f1dca1dfe4f9454667a6e6e0c479a9/src/command/check/check.ts#L93-L94

We probably need to improve the error message thrown in this case as there is really no file passed to the program https://github.com/quarto-dev/quarto-cli/blob/15a57c7ca18ac53688aecea39c79046f0744a871/src/core/dart-sass.ts#L66-L70

cc @dragonstyle

cscheid commented 1 year ago

Another quarto check improvement we could do is to make the quarto version report the very first thing, so if quarto check itself fails, we can at least know which version is being run...

cs-res-pub-ser-st commented 1 year ago
  1. Could you check that you don't have a _quarto.yml somewhere in the project directory or its parent?

There is a _quarto.yml at the root of the Quarto project, with the following in it:

project:
  title: "Quarto_test_HTML"

editor: visual
  1. Could you test to use Quarto from the command line?

I can access quarto from the RStudio Terminal, yes. Here's the output if I run quarto help:

$ quarto help

  Usage:   quarto
  Version: 1.3.353

  Description:

    Quarto CLI

  Options:

    -h, --help     - Show this help.
    -V, --version  - Show the version number for this program.

  Commands:

    render          [input] [args...]     - Render files or projects to various document types.
    preview         [file] [args...]      - Render and preview a document or website project.
    serve           [input]               - Serve a Shiny interactive document.
    create          [type] [commands...]  - Create a Quarto project or extension
    create-project  [dir]                 - Create a project for rendering multiple documents
    convert         <input>               - Convert documents to alternate representations.
    pandoc          [args...]             - Run the version of Pandoc embedded within Quarto.
    run             [script] [args...]    - Run a TypeScript, R, Python, or Lua script.
    add             <extension>           - Add an extension to this folder or project
    install         [target...]           - Installs an extension or global dependency.
    publish         [provider] [path]     - Publish a document or project. Available providers include:
    check           [target]              - Verify correct functioning of Quarto installation.
    help            [command]             - Show this help or the help of a sub-command.

Following up on recent comment by @cderv now, reading and processing.

cs-res-pub-ser-st commented 1 year ago

FYI the program that is ran is at bin\tools\dart-sass\sass.bat from your Quarto install directory. So I presume C:/PROGRA~1/RStudio/RESOUR~1/app/bin/quarto/bin/tools/dart-sass/sass.bat in your case. Maybe .bat file are blocked in your environment ?

Indeed, the system policy prohibits running sass.bat:

This program is blocked by group policy. For more information, contact your system administrator.

Am I completely out of luck on rendering to HTML because of this?

mcanouil commented 1 year ago

You could try setting theme: none but the results will be quite raw. Better to check with your IT department to make some kind of exceptions for C:/PROGRA~1/RStudio/RESOUR~1/app/bin/quarto/bin

cscheid commented 1 year ago

Is there a way for us to run sass without going through a batch file?

cs-res-pub-ser-st commented 1 year ago

Is there a way for us to run sass without going through a batch file?

I see dart.exe under the dart-sass/src folder and I am able to run it:

Usage: dart [<vm-flags>] <dart-script-file> [<script-arguments>]

Executes the Dart script <dart-script-file> with the given list of <script-arguments>.

Common VM flags:
--help or -h
  Display this message (add -v or --verbose for information about
  all VM options).
--packages=<path>
  Where to find a package spec file.
--define=<key>=<value> or -D<key>=<value>
  Define an environment declaration. To specify multiple declarations,
  use multiple instances of this option.
--snapshot-kind=<snapshot_kind>
--snapshot=<file_name>
  These snapshot options are used to generate a snapshot of the loaded
  Dart script:
    <snapshot-kind> controls the kind of snapshot, it could be
                    kernel(default) or app-jit
    <file_name> specifies the file into which the snapshot is written
--version
  Print the SDK version.

If it's a matter of running an initial configuration with dart.exe to compile the themes, I would think it's doable. If the HTML rendering requires sass.bat every time, then this would be a big ask in an enterprise security environment (arbitrary batch files are a security nightmare).

cderv commented 1 year ago

@cscheid

Another quarto check improvement we could do is to make the quarto version report the very first thing, so if quarto check itself fails, we can at least know which version is being run...

@cscheid I believe the dependencies check came before as without them, probably quarto would fail without them, and there was no information before that. Anyhow, we should discuss in another issue

Is there a way for us to run sass without going through a batch file?

sass.bat is provided by dart sass bundle available on their github. It is used to run the dart.exe in right context with correct command. I guess we could mimic this from Deno directly and check if that works. But we need to maintain any change they would made in that file.

But we need to make sure that no other script or process in our chain needs to call sass.bat. I think it should be fine as we bundle it, we should be the only ones to use it.

@dragonstyle should no better about all this

cscheid commented 1 year ago

if the HTML rendering requires sass.bat every time,

We do need to run SASS every time, because quarto can compile per-project custom SCSS themes.

then this would be a big ask in an enterprise security environment (arbitrary batch files are a security nightmare).

This is a longer discussion about the cargo-cult nature of enterprise security (and I understand it's not under your control) But, to be clear, arbitrary batch files are no worse than arbitrary binaries like dart.exe or arbitrary R code that gets executed in knitr. So, I think it would be reasonable to ask that if they allow quarto and knitr to be executed, they should also allow sass to run.

cs-res-pub-ser-st commented 1 year ago

But, to be clear, arbitrary batch files are no worse than arbitrary binaries like dart.exe or arbitrary R code that gets executed in knitr. So, I think it would be reasonable to ask that if they allow quarto and knitr to be executed, they should also allow sass to run.

Thanks @cscheid, this may imply that there are arbitrary batch files running in other parts of the pipeline already? I'm not aware of our IT staff allowing special exceptions for quarto and knitr batch files. If it's certainly the case that they've already made exceptions for quarto and knitr (I do not have knowledge of the under-the-hood processing pipeline involved with Quarto), then it makes it easier for me to request sass.bat as well. If not, then it will make it easier if the pipeline follows whatever else is happening under the hood with quarto and knitr (as those seemingly have no issues or exceptional requirements from my end user perspective).

Thanks @cderv, I'll keep an eye on this thread to see if there's anything I can do to help as an end user.

cscheid commented 1 year ago

Thanks @cscheid, this may imply that there are arbitrary batch files running in other parts of the pipeline already?

No, I was simply pointing out that blocking batch files that run inside the RStudio installation isn't likely to add any more security given what RStudio (and quarto) do as a product. Maybe if you communicate that to them it could help them open an exception.

The problem with us removing the batch file is that, as @cderv mentioned, this requires us to reimplement the batch file (and so we now have to track changes on theirs).

@cderv I can't find a sass.bat file on their repository; that makes me suspect this file doesn't change that often. In that case, it would be fine for us to reimplement that directly in our code, right?

cderv commented 1 year ago

I can't find a sass.bat file on their repository; that makes me suspect this file doesn't change that often. In that case, it would be fine for us to reimplement that directly in our code, right?

@cscheid sass.bat is part of the bundle for windows found at https://github.com/sass/dart-sass/releases This is built using dart toolchain by the CI. dart-sass using grinder and dart_cli_pkg. The latter is the tool that build the bundles for all the os and arch, including package repo like chocolatey. The .bat file is created by it -here is the mustache template: https://github.com/google/dart_cli_pkg/blob/main/lib/src/templates/standalone/executable.bat.mustache It is rendered based on dart pubspec in dart-sass, and then bundle with this .bat file is created during build package for windows step by dart-cli-pkg. This is what sass.bat looks like

@echo off
REM This script drives the standalone dart-sass package, which bundles together a
REM Dart executable and a snapshot of dart-sass.

set SCRIPTPATH=%~dp0
set arguments=%*
"%SCRIPTPATH%\src\dart.exe" "%SCRIPTPATH%\src\sass.snapshot" %arguments%

It seems the .bat template is 4 years old. So maybe we can safely replace it by our own Deno.run call, but we are taking action on another ecosystem. If we do that, we need to track any change that would happen in the future to this packaging process of dart-sass and how it works. Especially because if it is not changing often, we'll probably have forgotten this discussion when it will happen 😅

FWIW dart-sass is not the only tool with a .bat file I believe, TexLive will also have tlmgr.bat file on windows. Also, for now we also use a .bat file internally for safe execution on windows (as a workaround to insure correct quotation): https://github.com/quarto-dev/quarto-cli/blob/657c02e77bcf1764e462ef130e09b75411635593/src/core/windows.ts#L150-L152 Mainly use with tlmgr.bat

Anyhow, we should discuss this and I can do the work and test on windows.

cderv commented 1 year ago
cderv commented 3 weeks ago

I need to move that one release next again, but I really hope to tackle that in 1.7, especially as we move toward Deno.command()