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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permission error during stack upgrade 2.5.1 -> 2.9.1 on Windows #5968

Closed
adamburkegh opened this issue Dec 9, 2022 · 1 comment
Closed

Comments

@adamburkegh
Copy link

General summary/comments

Upgrade fails on Windows due to a permission error for a file move operation late in the install. Workaround included.

Steps to reproduce

Was upgrading an existing install from stack 2.5.1 to 2.9.1 as part of changing the stack.yaml resolver from

url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/16/22.yaml

to resolver: lts-18.19

Tried under git bash cygwin and windows command prompt first. Here is the output from windows command prompt with admin:

c:\somepath>stack upgrade
Current Stack version: 2.5.1, available download version: 2.9.1
Newer version detected, downloading
Querying for archive location for platform: windows-x86_64-static
Querying for archive location for platform: windows-x86_64
Downloading from: https://github.com/commercialhaskell/stack/releases/download/v2.9.1/stack-2.9.1-windows-x86_64.tar.gz
Download complete, testing executable
Version 2.9.1, Git revision 409d56031b4240221d656db09b2ba476fe6bb5b1 x86_64 hpack-0.35.0

Warning: Installation path C:\Users\Adam\AppData\Roaming\local\bin not found on the PATH environment variable.
New stack executable available at C:\Users\Adam\AppData\Roaming\local\bin\stack.exe
Also copying stack executable to C:\working\tools\stack\bin\stack.exe
Permission error when trying to copy: C:\working\tools\stack\bin\stack.exe.tmp: renameFile:renamePath:MoveFileEx "\\\\?\\C:\\working\\tools\\stack\\bin\\stack.exe.tmp" Just "\\\\?\\C:\\working\\tools\\stack\\bin\\stack.exe": permission denied (Access is denied.)
Should I try to perform the file copy using sudo? This may fail
Try using sudo? (y/n) y
Going to run the following commands:

-  sudo cp C:\Users\Adam\AppData\Roaming\local\bin\stack.exe C:\working\tools\stack\bin\stack.exe.tmp
-  sudo mv C:\working\tools\stack\bin\stack.exe.tmp C:\working\tools\stack\bin\stack.exe
Executable named sudo not found on path: [...]

Sure enough the directory will show an old stack.exe file and a new stack.exe.tmp file.

The file permissions were fine, and as I said I reran with admin.

Stack version

Old version: 2.5.1, fixed before getting the full version string.

New version

Version 2.9.1, Git revision 409d56031b4240221d656db09b2ba476fe6bb5b1 x86_64 hpack-0.35.0

Windows 10 version 21H2 (OS Build 19044.2251)

As this is a stack upgrade bug I am politely ignoring the request to test on the latest version.

Method of installation

  • Official binary, downloaded via haskellstack.org or from Stack's repository

Workaround

My workaround was to put a file called sudo.bat in the stack installation target directory. C:\working\tools\stack\bin\.

sudo.bat:

%*

This executes the arguments as a command, obviously without any of the elevated permissions you would usually get with sudo, which doesn't exist on Windows.

As inconsistent file operations are a recurring theme on Windows, I am raising the issue to at least document a workaround for others on the platform, or to track if others run into it.

Similar issues

The issue is similar to 1917 and 2426, but the exact error is different, and the workarounds mentioned in those, such as disabling virus check, or moving files around, didn't work for me.

@mpilgrem
Copy link
Member

mpilgrem commented Jan 8, 2023

@adamburkegh, thanks for reporting. I had a look at the underlying code.

I understand that the permissions problem arises (at least, primarily) because, on Windows, you can rename the file of a running executable, but you can't overwrite it. That seems to be recognised in the existing code in Stack.Setup.downloadStackExe (extract):

      case platform of
          Platform _ Cabal.Windows | FP.equalFilePath (toFilePath destFile) currExe -> do
              old <- parseAbsFile (toFilePath destFile ++ ".old")
              renameFile destFile old
              renameFile tmpFile destFile
          _ -> renameFile tmpFile destFile

but (strangely) not at Stack.Setup.performPathChecking, where it matters just as much (extract):

tmpFile <- parseAbsFile $ executablePath ++ ".tmp"
    eres <- tryIO $ do
      liftIO $ copyFile newFile tmpFile
      setFileExecutable (toFilePath tmpFile)
      liftIO $ renameFile tmpFile executablePath'

I have a pull request on the blocks that I think fixes this (I am about to write it up), but I am able to test it only on Windows. I need to find somebody who can test it does not break non-Windows Stack. The pull request also makes the 'sudo' interactions relevant only to non-Windows versions of Stack.

mpilgrem added a commit that referenced this issue Jan 8, 2023
Also, on Windows, does not offer the `sudo` command alternatives if attempting to write to the original file name of the running Stack executable results in a 'Permission' error.

Also, makes related Stack messages prettier.
mpilgrem added a commit that referenced this issue Jan 13, 2023
Fix #5968 New approach to overwriting existing Stack executable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants