Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cypress should not require write access of root folder #1281

Closed
itskingori opened this issue Feb 8, 2018 · 43 comments 路 Fixed by #7126
Closed

Cypress should not require write access of root folder #1281

itskingori opened this issue Feb 8, 2018 · 43 comments 路 Fixed by #7126
Assignees
Labels
type: unexpected behavior User expected result, but got another

Comments

@itskingori
Copy link

Why do we check if the root of the project is writeable? 馃憞 i.e. the fs.accessAsync(projectRoot, fs.W_OK)

exists: (projectRoot) ->
file = @_pathToFile(projectRoot, "cypress.json")
## first check if cypress.json exists
fs.statAsync(file)
.then ->
## if it does also check that the projectRoot
## directory is writable
fs.accessAsync(projectRoot, fs.W_OK)
.catch {code: "ENOENT"}, (err) =>
## cypress.json does not exist, we missing project
log("cannot find file %s", file)
@_err("PROJECT_DOES_NOT_EXIST", projectRoot, err)
.catch (err) =>
throw err if errors.isCypressErr(err)
## else we cannot read due to folder permissions
@_logReadErr(file, err)

cc:/ @zacblazic

@brian-mann
Copy link
Member

Because we seed the project with cypress.json and the cypress folder and example spec code, and plugins, and fixtures, etc.

@itskingori
Copy link
Author

@brian-mann Right. We're using this in Docker and common practice is to run the app as non-root. This means that we'd have to give the user access to write to the root of the app which is unnecessary since our app already has cypress.json and cypress/. Just giving you more context.

That said, seeding the project happens once and probably locally, right? Is this check really necessary?

@brian-mann
Copy link
Member

I see - with that said, we should only do this check if we believe we need to seed something in the root folder.

@itskingori
Copy link
Author

Yes. And this is why when the official Docker image set the user to a non-root user, many people were simply unable to work with it because of permission denied errors. See cypress-io/cypress-docker-images#10. The solution then was just to use root and let user's do whatever they want on their own images.

Just wanted to check with you guys if you're aware of this use case and the implications of this part of the code to that use case.

That said, I think my work is done. I'm not sure if I should keep this open or not. 馃

@brian-mann
Copy link
Member

I agree with your suggestion and we'll get this out in a patch release.

@brian-mann brian-mann modified the milestones: 3.0.1, 3.0.2 May 31, 2018
@Bhavik-P
Copy link

I am currently experiencing the same issue while running it on Bitrise. Is there an expected timeline as to when this will get completed? If there is a working solution already I'd love to take a look at it.

@brian-mann
Copy link
Member

@Bhavik-P @itskingori we talked about this at our team meeting today.

Even though we may not need to check for write access permissions to the project root - we still need write permissions to folders like cypress/videos or cypress/screenshots and the consensus was that these permissions would not be different than the projectRoot.

Can you two confirm or explain how this would NOT be the case? In other words, while we could remove this one specific check here, we'd have to add at least 2 more checks in other folders that are nested inside of the projectRoot. If the entire subtree has the same permissions it would simply error later in the process as opposed to here.

@Bhavik-P
Copy link

@brian-mann CI tools don't usually allow root access to apps. When I try to install Cypress locally (instead of globally) it doesn't pose any issues because the user has write-access to all subdirectories. The issue with this is that when I run the Cypress command, it says command not found. I have installed other libraries globally on Bitrise. Can you recommend something else that I can try? What if I don't want to use screenshots and videos?

@bahmutov
Copy link
Contributor

bahmutov commented Jun 25, 2018 via email

@Bhavik-P
Copy link

Bhavik-P commented Jun 25, 2018

Yes; installing it using npm install --save-dev cypress leads to a bash error command not found

@brian-mann
Copy link
Member

brian-mann commented Jun 25, 2018

@Bhavik-P to get on the same page I think we need to define terms a bit better.

You say: root access to apps but this makes no sense to me. Cypress does not require root access - it requires write access to the project's root directory. This is simply the folder that contains cypress.json. It would be the same folder that's created with the git clone command.

We only write inside of that project folder. This is the same level of access that any node_module would need when running npm install.

In fact... how does your project ever run npm install? That needs the same level of write access as Cypress does to node_modules.

@Bhavik-P
Copy link

@brian-mann
I was trying to install the package globally instead of with the project directory. When doing so, it required root access to write folders which for obvious reasons cannot be permitted. When I installed it in the project directory, I was able to install it, however, I couldn't just make a call to Cypress (cypress run) as I would when I globally installed it. This is where I went wrong. I knew something had to be wrong on my end so I looked at the docs and realized I missed a very important step. I needed to run cypress as such: $(npm bin)/cypress. I appreciate your time and thanks for the quick responses.

@brian-mann
Copy link
Member

@itskingori do you mind weighing in on my comment here: #1281 (comment)

We decided to fix this issue but once we investigated it, it made no sense how or why this would solve anything.

We'd really like to understand how Cypress doesn't have write access to the project root (where cypress.json is stored) and yet node_modules would have write access to the same exact folder?

@brian-mann brian-mann removed this from the 3.0.2 milestone Jun 28, 2018
@fgm
Copy link

fgm commented Jun 28, 2018

Just have a similar problem, just worse: Cypress tries to create a directory below the system root, not just the project root, like /.Trash-1002, which I suspect might be related.

@DavideDaniel
Copy link

DavideDaniel commented Jul 5, 2018

Here is Cypress attempting to gain access to root of a docker image where our install is happening. Please note that this isn't even us running cypress. The project is simply running it's normal build process but this time we have added cypress to the project and during a yarn/npm install cypress attempts to access root to make a /.cache/Cypress directory. It seems like an install script that cypress attempts to run regardless of whether it's CI or not and in our jenkins pipeline it will fail as these are being built on docker images. Our options then are either to disable all scripts which could be detrimental with other dependencies, or to remove Cypress completely from the project... which we would rather not do... just yet...

error An unexpected error occurred: "/tmp/jenkins-1112/workspace/xxxxxxx-7-4-TK7RUNRBZAPATDAVC@2/node_modules/cypress: Command failed.

Exit code: 1

Command: sh

Arguments: -c node index.js --exec install

Directory: /tmp/jenkins-1112/workspace/xxxxxxx-7-4-TK7RUNRBZAPATDAVC@2/node_modules/cypress

Output:

Cypress cannot write to the cache directory due to file permissions

----------



Failed to access /.cache/Cypress:



EACCES: permission denied, mkdir '/.cache/Cypress'

----------



Platform: linux (Debian - 8.10)

Cypress Version: 3.0.2".

info If you think this is a bug, please open a bug report with the information provided in "/tmp/jenkins-1112/workspace/xxxxxxx-7-4-TK7RUNRBZAPATDAVC@2/yarn-error.log".

info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

error An unexpected error occurred: "Command failed.

Exit code: 1

Command: sh

Arguments: -c yarn install --frozen-lockfile

Directory: /tmp/jenkins-1112/workspace/xxxxxxx-7-4-TK7RUNRBZAPATDAVC@2

Output:

".

info If you think this is a bug, please open a bug report with the information provided in "/tmp/jenkins-1112/workspace/xxxxxxx-7-4-TK7RUNRBZAPATDAVC@2/yarn-error.log".

info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

error An unexpected error occurred: "Command failed.

Exit code: 1

Command: sh

Arguments: -c yarn log:sha && yarn i

Directory: /tmp/jenkins-1112/workspace/xxxxxxx-7-4-TK7RUNRBZAPATDAVC@2

Output:

".

info If you think this is a bug, please open a bug report with the information provided in "/tmp/jenkins-1112/workspace/xxxxxxx-7-4-TK7RUNRBZAPATDAVC@2/yarn-error.log".

info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

script returned exit code 1```

@alexeagle
Copy link

Here's Angular's use case: for performance, we are rolling out a remote execution system where a farm of machines can run build/test actions.
When a test runs remotely, we copy over the declared inputs, run the test executor, then collect the outputs written to specified locations back to your machine. The remote execution uses a containerized FS where we prevent writes to the project directory, as these would be lost and not copied back to your machine.

I would like to run Cypress on such a remote build/test farm, which requires that we be able to configure the locations where it writes files, and it shouldn't check for write access in other locations.

@brian-mann
Copy link
Member

@DavideDaniel per our installation docs we are pretty clear that Cypress will cache itself in the system cache folder appropriate for each operating system. In linux it would be /.cache - many other modules do this as well. This is very common, even moreso common for modules to store global configuration in places like /.config.

At any rate - per our installation docs you can with a simple environment variable change the location of this cache yourself here: https://docs.cypress.io/guides/getting-started/installing-cypress.html#Advanced

You can either skip the binary installation (if you have it cached elsewhere) or control where you want it to be installed.

What do you do about caching other things like your node_modules? Whatever mechanism you use for those you could use for Cypress which would prevent it from even needing to install when Jenkins loads.

@brian-mann
Copy link
Member

@fgm see my comment here: likely this is the same issue with caching #1281 (comment)

@brian-mann
Copy link
Member

@alexeagle can you explain how if you want to disable write access to the project - Cypress would be able to generate any assets from the run? Things like logs, screenshots, videos, etc?

Can you suggest to us what you'd like Cypress to do instead?

Currently you can turn off taking screenshots and video in the configuration. Although we do have a hardcoded check to ensure the project root has write access. We can remove that check (or turn it into a warning) if need be. But I still don't understand how this really achieves anything considering you won't be able to capture anything from the test runs.

@alexeagle
Copy link

alexeagle commented Jul 7, 2018 via email

@fgm
Copy link

fgm commented Jul 9, 2018

@brian-mann thanks for the answer /.cache is rather uncommon AFAIK and not compliant with the linux Filesystem Hierarchy Standard. Per-user caches should go into ~/.cache, so typically in /root/.cache for caches for the root user ; while global runtime cache like these should probably go in /var/cache (/run/cache in the upcoming version of the FHS).

@brian-mann
Copy link
Member

@fgm sorry I did not explain correctly - it DOES go into the user's ~/.cache directory. We use this module here to create the paths: https://github.com/LinusU/node-cachedir

You can see that's where it puts it. I guess I'm now confused what the actual problem is now since this is the correct and intended behavior of how it installs.

@alexeagle You can already do exactly just that - Cypress provides options via its cypress.json to configure exactly where you want those folders to go. You can even override those values with environment variables specifically for CI.

@cypress-bot cypress-bot bot removed the stage: needs a test Needs 1 or more tests written for PR label Feb 26, 2020
@cypress-bot cypress-bot bot added stage: ready for work The issue is reproducible and in scope and removed stage: needs review The PR code is done & tested, needs review labels Apr 10, 2020
@cypress-bot cypress-bot bot added stage: work in progress There is an open PR for this issue [WIP] and removed stage: ready for work The issue is reproducible and in scope labels Apr 23, 2020
@cypress-bot cypress-bot bot added stage: needs review The PR code is done & tested, needs review stage: work in progress There is an open PR for this issue [WIP] and removed stage: work in progress There is an open PR for this issue [WIP] stage: needs review The PR code is done & tested, needs review labels May 4, 2020
@cypress-bot cypress-bot bot added stage: needs review The PR code is done & tested, needs review stage: work in progress There is an open PR for this issue [WIP] and removed stage: work in progress There is an open PR for this issue [WIP] stage: needs review The PR code is done & tested, needs review labels May 7, 2020
@thecodejack
Copy link

I am also having permissions issue but creating a lock file inside /tmp/cypress. Since the machine can be used by multiple users in our case, if one user ran tests, other user can't coz of loosing control of /tmp/cypress. I am getting following error.

[OperationalError: EACCES: permission denied, open '/tmp/cypress/4fa88ed0720f436f49e09ac33f63413a.lock'

] {  cause: [Error: EACCES: permission denied, open '/tmp/cypress/4fa88ed0720f436f49e09ac33f63413a.lock'    ] {
    errno: -13,
    code: 'EACCES',
    syscall: 'open',
    path: '/tmp/cypress/4fa88ed0720f436f49e09ac33f63413a.lock'
  },
  isOperational: true,
  errno: -13,
  code: 'EACCES',
  syscall: 'open',
  path: '/tmp/cypress/4fa88ed0720f436f49e09ac33f63413a.lock'
}
Error: EACCES: permission denied, open '/tmp/cypress/4fa88ed0720f436f49e09ac33f63413a.lock'

Tried different ways mentioned above but didn't solve the issue.

@lmiller1990
Copy link
Contributor

lmiller1990 commented May 10, 2020

An option to turn off the write check would be useful. The problem most of have is likely a lack of dev-ops and linux permission experience, however if we are just running tests and writing to stdout, dropping the write access might make adopting Cypress easier for many people.

@cypress-bot cypress-bot bot added stage: needs review The PR code is done & tested, needs review and removed stage: work in progress There is an open PR for this issue [WIP] labels May 11, 2020
@cypress-bot
Copy link
Contributor

cypress-bot bot commented May 12, 2020

The code for this is done in cypress-io/cypress#7126, but has yet to be released.
We'll update this issue and reference the changelog when it's released.

@cypress-bot cypress-bot bot removed the stage: needs review The PR code is done & tested, needs review label May 12, 2020
@cypress-bot
Copy link
Contributor

cypress-bot bot commented May 20, 2020

Released in 4.6.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v4.6.0, please open a new issue.

@cypress-bot cypress-bot bot locked as resolved and limited conversation to collaborators May 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: unexpected behavior User expected result, but got another
Projects
None yet