Skip to content

Exports added by :with are ineffective when :user is specified #490

@64kramsystem

Description

@64kramsystem

When a command is mapped, (:should_map?), both :with and :user are invoked.

In both builder methods, the environment variables specified are intended to be inherited by the subshell.

Say that we have the env var MYVAR=myvar, and the command mycommand, which needs to be run as the user myuser. The relevant builder methods are:

    def with(&_block)
      env_string = environment_string
      return yield if env_string.empty?
      "( export #{env_string} ; #{yield} )"
    end

    def user(&_block)
      return yield unless options[:user]
      env_string = environment_string
      "sudo -u #{options[:user].to_s.shellescape} #{env_string + " " unless env_string.empty?}-- sh -c #{yield.shellescape}"
    end

this will generate something like:

( export MYVAR=myvar ; sudo -u myuser MYVAR=myvar -- sh -c command )

The problem is that the export is ineffective, because exports are not inherited by the sudo subshell.

While this is harmless, it clutters the generated commands, and it's also semantically incorrect (because it's ineffective) and confusing.

This could be avoided by just yielding the the builder block if options[:user] is set:

    def with(&_block)
>      # Exports are ineffective on non-login (sudo) shells; in this case, the :user builder takes
>      # care of setting them.
>      return yield if options[:user]
      env_string = environment_string
      return yield if env_string.empty?
      "( export #{env_string} ; #{yield} )"
    end

This makes the (internal) commands output more readable (and understandable). While this has no effect on the end users, it helps understanding those who approach Capistrano/Sshkit development (at least, it did it for me 😬).

If this is approved (either in this form or another), I can easily open a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions