Skip to content

Conversation

alexander-smolyakov
Copy link
Contributor

@alexander-smolyakov alexander-smolyakov commented May 5, 2023

Dev container name:

  • universal

Description:

This PR addresses the issue with permissions when the customer is trying installs ruby gems, during installation customer is facing the following error:

codespace ➜ / $ gem install racc
Fetching racc-1.6.2.gem
Building native extensions. This could take a while...
ERROR:  While executing gem ... (Errno::EACCES)
    Permission denied @ dir_s_mkdir - /usr/local/rvm/gems/ruby-3.1.4/extensions/x86_64-linux/3.1.0/racc-1.6.2
        /usr/local/rvm/rubies/ruby-3.1.4/lib/ruby/3.1.0/fileutils.rb:243:in `mkdir'

The issue is related to the fact that thex86_64-linux folder can be accessed only by the root user:

codespace ➜ / $ ls -ld /usr/local/rvm/gems/ruby-3.1.4/extensions
drwxrwsr-x 1 codespace rvm 4096 Apr 21 05:09 /usr/local/rvm/gems/ruby-3.1.4/extensions
codespace ➜ / $ ls -l /usr/local/rvm/gems/ruby-3.1.4/extensions/
total 4
drwxr-sr-x 3 root rvm 4096 Apr 21 05:09 x86_64-linux

The issue started to appear after recent changes to the ruby feature:

These changes triggered the issue with the Jekyll feature. The issue is related to the Jekyll feature not applying permissions for all required folders.

Detailed issue explanation

We install the ruby-debug-ide package in version v1.0.9 of the ruby feature. Because of it, RubyGems create the x86_64-linux folder in the extensions folder. The x86_64-linux folder contains packages that we install via the gem install command. When we apply chown and chmod commands against the rvm folder, we also apply them for the x86_64-linux folder so that the codespace user has all the required permissions to install packages.

extensions folder layout (ruby feature v1.0.9):

codespace ➜ ~ $ tree -up /usr/local/rvm/gems/ruby-3.1.4/extensions/
/usr/local/rvm/gems/ruby-3.1.4/extensions/
└── [drwxrwsr-x codespace]  x86_64-linux
    └── [drwxrwsr-x codespace]  3.1.0
        ├── [drwxrwsr-x codespace]  debase-0.2.4.1
        │   ├── [-rw-rw-r-- codespace]  gem_make.out
        │   └── [-rw-rw-r-- codespace]  mkmf.log
        ├── [drwxrwsr-x codespace]  debase-0.2.5.beta2
        │   ├── [-rwxrwxr-x codespace]  attach.so
        │   ├── [-rwxrwxr-x codespace]  debase_internals.so
        │   ├── [-rw-rw-r-- codespace]  gem.build_complete
        │   ├── [-rw-rw-r-- codespace]  gem_make.out
        │   └── [-rw-rw-r-- codespace]  mkmf.log
        └── [drwxrwsr-x codespace]  ruby-debug-ide-0.7.3
            ├── [-rw-rw-r-- codespace]  gem.build_complete
            └── [-rw-rw-r-- codespace]  gem_make.out

5 directories, 9 files

With version v1.0.10, we no longer install the ruby-debug-ide package, and as a result, the extensions folder is empty.

extensions folder layout (ruby feature v1.0.10):

codespace ➜ ~ $ tree -up /usr/local/rvm/gems/ruby-3.1.4/extensions/
/usr/local/rvm/gems/ruby-3.1.4/extensions/

0 directories, 0 files

The jekyll feature now creates the x86_64-linux folder. During feature installation, the root user executes the gem install command, as a result of which only the root user has write access to the x86_64-linux folder.

extensions folder layout (ruby feature v1.0.10 + jekyll feature):

codespace ➜ ~ $ tree -up /usr/local/rvm/gems/ruby-3.1.4/extensions/
/usr/local/rvm/gems/ruby-3.1.4/extensions/
└── [drwxr-sr-x root    ]  x86_64-linux
    └── [drwxr-sr-x root    ]  3.1.0
        ├── [drwxr-sr-x root    ]  eventmachine-1.2.7
        │   ├── [-rwxr-xr-x root    ]  fastfilereaderext.so
        │   ├── [-rw-r--r-- root    ]  gem.build_complete
        │   ├── [-rw-r--r-- root    ]  gem_make.out
        │   ├── [-rw-r--r-- root    ]  mkmf.log
        │   └── [-rwxr-xr-x root    ]  rubyeventmachine.so
        ├── [drwxr-sr-x root    ]  ffi-1.15.5
        │   ├── [-rwxr-xr-x root    ]  ffi_c.so
        │   ├── [-rw-r--r-- root    ]  gem.build_complete
        │   ├── [-rw-r--r-- root    ]  gem_make.out
        │   └── [-rw-r--r-- root    ]  mkmf.log
        └── [drwxr-sr-x root    ]  http_parser.rb-0.8.0
            ├── [-rw-r--r-- root    ]  gem.build_complete
            ├── [-rw-r--r-- root    ]  gem_make.out
            └── [-rwxr-xr-x root    ]  ruby_http_parser.so

5 directories, 12 files

The current permission sync logic works only against the /usr/local/rvm/rubies/default/bin folder (which is just a symlink to the latest ruby version), while all gems are stored in /usr/local/rvm/gems/ruby-<version>/extensions/ folder.

permission sync logic:

chown -R "${USERNAME}:rvm" "${GEMS_DIR}/"
chmod -R g+r+w "${GEMS_DIR}/"
find "${GEMS_DIR}" -type d | xargs -n 1 chmod g+s

/usr/local/rvm/rubies/default/bin folder layout:

codespace ➜ ~ $ tree -up /usr/local/rvm/rubies/default/bin
/usr/local/rvm/rubies/default/bin
├── [-rwxrwxr-x codespace]  bundle
├── [-rwxrwxr-x codespace]  bundler
├── [-rwxrwxr-x codespace]  erb
├── [-rwxrwxr-x codespace]  executable-hooks-uninstaller
├── [-rwxrwxr-x codespace]  gem
├── [-rwxrwxr-x codespace]  irb
├── [-rwxrwxr-x codespace]  racc
├── [-rwxrwxr-x codespace]  rake
├── [-rwxrwxr-x codespace]  rbs
├── [-rwxrwxr-x codespace]  rdbg
├── [-rwxrwxr-x codespace]  rdoc
├── [-rwxrwxr-x codespace]  ri
├── [-rwxrwxr-x codespace]  ruby
├── [-rwxrwxr-x codespace]  ruby_executable_hooks
└── [-rwxrwxr-x codespace]  typeprof

Fix:

To fix the issue, we need to rework the permission-applying logic to make sure that the /usr/local/rvm/gems/default/extensions folder inside the ruby version manager can be accessed by the codespace user.

Changelog:

  • Adjusted permission-applying logic to apply permissions for the /usr/local/rvm/gems/default/extensions folder;
  • Implemented the checkDirectoryOwnership generic function to validate directory ownership by user and group;
  • Added test to ensure that the codespace user has ownership over the extension directory.

Attached related issue:

Checklist:

  • Checked that applied changes work as expected

- Change the setting up permission logic to be compatible with ruby feature
@alexander-smolyakov alexander-smolyakov requested a review from a team as a code owner May 5, 2023 11:56
- Add function to check directory ownership
- Add test to ensure that `codespace` user has ownership over `extension` directory
Copy link
Member

@samruddhikhandale samruddhikhandale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thank you!

@samruddhikhandale samruddhikhandale merged commit 98b5b1d into devcontainers:main May 11, 2023
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

Successfully merging this pull request may close these issues.

2 participants