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

Saving files fails if officer is installed read-only #549

Closed
alexvorobiev opened this issue Feb 2, 2024 · 6 comments
Closed

Saving files fails if officer is installed read-only #549

alexvorobiev opened this issue Feb 2, 2024 · 6 comments

Comments

@alexvorobiev
Copy link

alexvorobiev commented Feb 2, 2024

These lines in read_docx:

file.copy(

file.copy(

copy the respective files from the package's installation directory and then modify them before saving the output, so if Officer is installed read-only, the saving fails:

library(officer)

d <- read_docx()
d <- body_add_par(d, 'title')
print(d, target = 'test.docx')
> print(d, target = 'test.docx')
Error in write_xml.xml_document(private$doc, file = private$filename) : 
  Error closing file
In addition: Warning messages:
1: In write_xml.xml_document(private$doc, file = private$filename) :
  Permission denie [1501]
2: In write_xml.xml_document(private$doc, file = private$filename) :
  Permission denie [1501]

One solution would be to add copy.mode = FALSE to the file.copy calls, so that the file mode attributes are not preserved.

In enterprise settings it is not uncommon to have a centralized library of packages where everything is installed read-only and maintained by designated users/teams. Another use case which is quickly gaining popularity is using Nix package manager for maintaining data science environments. Nix also installs everything read-only.

@davidgohel
Copy link
Owner

I am not able to reproduce and it's been years that I am using it in * enterprise* context, so I am a little suspicious :)

where everything is installed read-only

This is from a docker on my machine - packages are in /opt/R/4.3.2/lib/R/library own by root:
Capture d’écran 2024-02-03 à 09 39 06

I can run your example with shiny user (I just had this machine ready so I used it with shiny user)

shiny@ddf0f64eef52:~$ R

R version 4.3.2 (2023-10-31) -- "Eye Holes"
Copyright (C) 2023 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

  Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> library(officer)
ar(d, 'title')
print(d, target = 'test.docx')> 
> d <- read_docx()
> d <- body_add_par(d, 'title')
> print(d, target = 'test.docx')
> getwd()
[1] "/home/shiny"
> file.info(system.file(package = "officer"))
                                   size isdir mode               mtime
/opt/R/4.3.2/lib/R/library/officer 4096  TRUE  755 2024-02-03 08:35:11
                                                 ctime               atime uid
/opt/R/4.3.2/lib/R/library/officer 2024-02-03 08:35:43 2024-02-03 08:35:58   0
                                   gid uname grname
/opt/R/4.3.2/lib/R/library/officer   0  root   root

I think instead the issue is in your system where you set tempdir() as read only.

package_dir <- tempfile()

@alexvorobiev
Copy link
Author

alexvorobiev commented Feb 3, 2024

The crucial part in your case is that you have the write permission for the owner of the files, so that bit will be carried over when the files are copied (by default copy.mode is T, so it preserves all the permission bits). Depending on how the centralized library is deployed it could be not the case. For instance, the "Nix store" (the immutable (subject only to garbage collection) storage for all the packaged Nix manages) doesn't have the "w" bit set even for the owner. Actually, the problem is even documented on the official Nix wiki https://nixos.wiki/wiki/R (scroll all the way down), I just decided to step through the execution in the debugger to see what is going on. Try removing the w bit on the two template xml files in the directory where the package is installed and you will get the behavior I described.

❯ ls -l /nix/store/*-r-officer-*/library/officer
total 72
-r--r--r-- 1 root root  3436 Dec 31  1969 DESCRIPTION
dr-xr-xr-x 2 root root  4096 Dec 31  1969 doc_examples
dr-xr-xr-x 3 root root  4096 Dec 31  1969 help
dr-xr-xr-x 2 root root  4096 Dec 31  1969 html
-r--r--r-- 1 root root  6549 Dec 31  1969 INDEX
-r--r--r-- 1 root root    36 Dec 31  1969 LICENSE
dr-xr-xr-x 2 root root  4096 Dec 31  1969 Meta
-r--r--r-- 1 root root  9061 Dec 31  1969 NAMESPACE
-r--r--r-- 1 root root 18837 Dec 31  1969 NEWS.md
dr-xr-xr-x 2 root root  4096 Dec 31  1969 R
dr-xr-xr-x 2 root root  4096 Dec 31  1969 template
❯ ls -ld /nix/store/*-r-officer-*/library/officer
dr-xr-xr-x 8 root root 4096 Dec 31  1969 /nix/store/ci1v4gcwhx9mwnshqxab7pb0d8vs6cn5-r-officer-0.6.3/library/officer

@davidgohel
Copy link
Owner

OK, I did the requested changes, is it possible for you to test?

@alexvorobiev
Copy link
Author

It looks like the problem is fixed!

The current CRAN version (with the issue):

❯ nix-shell -p R -p rPackages.officer --run 'Rscript -e "library(officer); d <- read_docx(); d <- body_add_par(d, \"title\"); print(d, target = \"~/test.docx\")"'
Error in write_xml.xml_document(private$doc, file = private$filename) : 
  Error closing file
Calls: print ... print.rdocx -> <Anonymous> -> write_xml -> write_xml.xml_document
In addition: Warning messages:
1: In write_xml.xml_document(private$doc, file = private$filename) :
  Permission denie [1501]
2: In write_xml.xml_document(private$doc, file = private$filename) :
  Permission denie [1501]
Execution halted

The latest Github commit:

❯ nix-shell -p R -p '(rPackages.officer.overrideAttrs (_: {src = (fetchTarball "https://github.com/davidgohel/officer/archive/dbb27faa10e6a520092716748992d69271bf3c94.tar.gz");}))' --run 'Rscript -e "library(officer); d <- read_docx(); d <- body_add_par(d, \"title\"); print(d, target = \"~/test.docx\"); system(\"ls -l ~/test.docx\")"'
-rw-r--r-- 1 alex users 12567 Feb  5 12:50 /home/alex/test.docx

Thank you!

@davidgohel
Copy link
Owner

cool, thank you for taking the time to test it

Copy link

github-actions bot commented Aug 8, 2024

This old thread has been automatically locked. If you think you have found something related to this, please open a new issue and link to this old issue if necessary.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 8, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants