LoginSignup
2
0

More than 1 year has passed since last update.

tmpfs が noexec だと、Rパッケージのインストールに失敗することがある

Last updated at Posted at 2021-12-06

R Advent Calendar 2021 の7日目の記事です。

Rのパッケージをインストールできないのは、 /tmp にマウントした tmpfs が noexec なのが原因だった、という話です。エラーメッセージからは原因が分かりにくいので、状況を再現しました。

実行環境

Dockerイメージを、以下の Dockerfile ファイルから作成します。あえて rocker/tidyverse を使っていません。本文書の実行環境は、 Windows 10 + WSL2 + R 3.6.3 です。

FROM ubuntu:focal

ENV TZ=Asia/Tokyo
RUN apt-get update && apt-get install -y tzdata
RUN apt-get install -y r-base
RUN apt-get install -y wget gdebi-core
RUN wget https://download2.rstudio.org/server/bionic/amd64/rstudio-server-2021.09.1-372-amd64.deb
RUN gdebi --non-interactive rstudio-server-2021.09.1-372-amd64.deb

RUN apt-get install -y libssl-dev libcurl4-openssl-dev libxml2-dev
RUN R -e 'install.packages("remotes")'
RUN Rscript -e 'remotes::install_version("devtools")'

RUN adduser --disabled-password --gecos "" rstudio
RUN echo "rstudio:rstudio" | chpasswd
CMD rstudio-server start && tail -f < /dev/null

docker-compose.yml を以下のように書きます。最初は /tmp の tmpfs を exec にしておきます。

version: '3'
services:
  installation_failed:
    build: .
    image: installation_failed
    ports:
      - 8787:8787
    tmpfs:
      - /tmp:exec
    volumes:
      - .:/home/rstudio/work

この Docker イメージをビルドして起動すると(必要なら sudo をつけてください)、 http://example.com:8787/ の RStudio Server にログインできます。ホスト名は localhost などに適宜読み替えてください。先の Dockerfile に書いた通り、ユーザとパスワードは rstudio です。

docker-compose -f docker-compose.yml build
docker-compose -f docker-compose.yml up -d

tmpfs が exec のとき

data.table パッケージをインストールしましょう。 HTTP proxy などに止められなければ、無事インストールできるはずです。

install.packages("data.table")
library(data.table)

pkgbuild を使って、パッケージをビルドできるかどうか調べます。ビルドできますね。

pkgbuild::check_build_tools(debug = TRUE)
## Your system is ready to build packages!

pkgbuild::check_compiler(debug = TRUE)
## Trying to compile a simple C file
## Running /usr/lib/R/bin/R CMD SHLIB foo.c
## gcc -std=gnu99 -I"/usr/share/R/include" -DNDEBUG -fpic -g -O2 -fdebug-prefix-map=/build/r-base-jbaK_j/r-base-3.6.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -c foo.c -o foo.o
## gcc -std=gnu99 -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o foo.so foo.o -L/usr/lib/R/lib -lR
## [1] TRUE

tmpfs が noexec のとき

先ほどの docker-compose.yml の、 /tmp:exec を /tmp:noexec に変えます。これを docker-compose-noexec.yml として保存して、

version: '3'
services:
  installation_failed:
    build: .
    image: installation_failed
    ports:
      - 8787:8787
    tmpfs:
      - /tmp:noexec
    volumes:
      - .:/home/rstudio/work

先ほどと同じ Docker イメージを docker-compose-noexec.yml で起動します(必要なら sudo をつけて実行してください)。

docker-compose -f docker-compose.yml down
docker-compose -f docker-compose-noexec.yml up -d

pkgbuild を使って、パッケージをビルドできるかどうか調べます。ビルドツールはありますが、コンパイルはできないようです。

pkgbuild::check_build_tools(debug = TRUE)
## Your system is ready to build packages!

pkgbuild::check_compiler(debug = TRUE)
## Trying to compile a simple C file
## Running /usr/lib/R/bin/R CMD SHLIB foo.c
## gcc -std=gnu99 -I"/usr/share/R/include" -DNDEBUG -fpic -g -O2 -fdebug-prefix-map=/build/r-base-jbaK_j/r-base-3.6.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -c foo.c -o foo.o
## gcc -std=gnu99 -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o foo.so foo.o -L/usr/lib/R/lib -lR
## Error: Failed to compile C code

data.table パッケージをインストールしましょう。 configure が実行可能でない、と言われてインストールに失敗します。

install.packages("data.table")
## Installing package into '/home/rstudio/R/x86_64-pc-linux-gnu-library/3.6'
## (as 'lib' is unspecified)
## trying URL 'https://cloud.r-project.org/src/contrib/data.table_1.14.2.tar.gz'
## Content type 'application/x-gzip' length 5301817 bytes (5.1 MB)
## ==================================================
## downloaded 5.1 MB
##
## * installing *source* package 'data.table' ...
## ** package 'data.table' successfully unpacked and MD5 sums checked
## ** using staged installation
## ERROR: 'configure' exists but is not executable -- see the 'R Installation and Administration Manual'
## * removing '/home/rstudio/R/x86_64-pc-linux-gnu-library/3.6/data.table'
## Warning in install.packages :
##   installation of package 'data.table' had non-zero exit status
##
## The downloaded source packages are in
##  '/tmp/RtmpatoM4r/downloaded_packages'

エラーメッセージから /tmp で data.table パッケージをビルドしようとして失敗したことが分かります。しかしこのエラーメッセージだと、原因が分かりにくいですね。実際にこのようなやり取りが GitHub の Issues でありました。

/tmp が noexec かどうかは、 findmnt コマンドで確認できます。

findmnt /tmp
## TARGET SOURCE FSTYPE OPTIONS
## /tmp   tmpfs  tmpfs  rw,nosuid,nodev,noexec,relatime

自作したRパッケージをインストールする

自作したRパッケージが依存する、外部のRパッケージは、 DESCRIPTION ファイルの Imports: に書きます。ここに data.table があると、やはりパッケージのビルドでエラーになります。

tmpfs が exec のとき

  1. install.packages("data.table") で data.table をインストールします
  2. RStudio の Build タブを開きます
  3. Check を押してパッケージを検査すると、最後まで実行されて結果が出ます
  4. Install and Restart を押してインストールする処理も上手くいきます

tmpfs が noexec のとき

  1. install.packages("data.table") は失敗するので、結果を無視します
  2. RStudio の Build タブを開きます
  3. RStudio の Build タブを開き、 Check を押してパッケージを検査すると、以下のメッセージが出ます
==> devtools::check(document = FALSE)

-- Building ------------------------------- installationfailedsample --
Setting env vars:
* CFLAGS    : -Wall -pedantic
* CXXFLAGS  : -Wall -pedantic
* CXX11FLAGS: -Wall -pedantic
-----------------------------------------------------------------------
v  checking for file '/home/rstudio/work/sample/DESCRIPTION' ...
-  preparing 'installationfailedsample':
v  checking DESCRIPTION meta-information ... OK
-  checking for LF line-endings in source and make files and shell scripts
-  checking for empty or unneeded directories
-  building 'installationfailedsample_0.1.0.tar.gz'

-- Checking ------------------------------- installationfailedsample --
Setting env vars:
* _R_CHECK_CRAN_INCOMING_REMOTE_: FALSE
* _R_CHECK_CRAN_INCOMING_       : FALSE
* _R_CHECK_FORCE_SUGGESTS_      : FALSE
* NOT_CRAN                      : true
Error: Could not find tools necessary to compile a package
Call `pkgbuild::check_build_tools(debug = TRUE)` to diagnose the problem.
Execution halted

Exited with status 1.

"Could not find tools necessary to compile a package" というエラーメッセージから、 tmpfs が原因であることを突き止めるのは大変です。gcc と g++ はインストールされているので、 pkgbuild::check_build_tools(debug = TRUE) は正常終了します。そういう理由からこの記事を書きました。

サンプルコード

コード一式を GitHub に置きました。お役に立てれば幸いです。

2
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0