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

Feature request: Vagrant Up then Remote Connection #18

Open
JonTheNiceGuy opened this issue Nov 19, 2019 · 1 comment
Open

Feature request: Vagrant Up then Remote Connection #18

JonTheNiceGuy opened this issue Nov 19, 2019 · 1 comment

Comments

@JonTheNiceGuy
Copy link

It would be useful if we can use this plugin (or something similar) to perform vagrant up, then vagrant ssh to achieve connection to the remote machine (with vscode-remote-release).

I have no idea if this is feasible or even sensible, but it would be interesting!

@depthoffocus
Copy link

depthoffocus commented Nov 19, 2020

It would be useful!

In the interim I use a strategy to automatically maintain the remote hosts list, which is actually all you need. It solves the problem of the machines coming up on different ports each time.

I thought it worth describing here in case people find it interesting or useful.

Visual Studio Code can parse include directives in .ssh/config, but not wildcards (at the moment).

So I use triggers to regenerate a set of SSH config include files from vagrant ssh-config and store them in a known directory. I then have a method that generates a single index file including each of them, and in turn I include that from .ssh/config.

Basically:

  • when bringing up/provisioning/reloading/resuming a machine, I dump the output from vagrant ssh-config into a file in a known directory (inside $HOME/.vagrant.d)
  • when destroying/halting/suspending machines, I remove the file
  • in each case I rebuild the master include file

Then each trigger action will maintain your remote SSH hosts list for you, without needing to restart vscode.

The triggers in Vagrantfile:

 config.trigger.after [:up, :provision, :reload, :resume] do |trigger|
    trigger.ruby do |env,machine|
      MyClass.up_trigger(env, machine)
    end
  end
  
  config.trigger.after [:destroy, :halt, :suspend] do |trigger|
    trigger.ruby do |env,machine|
       MyClass.down_trigger(env, machine)
    end
  end

Then in MyClass is the following code.

This function defines an SSH configuration directory within .vagrant, where I will write individual files containing the output of vagrant ssh-config:

    def ssh_config_dir
      cfg_dir = Pathname.new(Vagrant.user_data_path).join('mydir', 'ssh')
      cfg_dir.mkpath unless cfg_dir.exist?
      cfg_dir
    end

This function builds a master include file of all of those files, which gets stored in the same directory (so, err, don't call a vagrant box "include" ;-):

    def build_ssh_include_file(ssh_dir)
      return if !File.directory? ssh_dir

      include_file = [ ]
      Dir.entries(ssh_dir).each do |item| 
        next if File.directory? item  
        next if item == '.' or item == '..'
        next if item !~ /\.config$/i
        next if item == 'include.config'
        path = ssh_dir.join(item)
        include_file << "Include #{path}"
      end

      ssh_dir.join('include.config').write("# all vagrant hosts\n" + include_file.join("\n"))
    end

The up_trigger function uses bash to invoke vagrant ssh-config to write the SSH config to a file. So this is sort of Unix-only for now. I guess I could directly invoke the underlying Vagrant code that produces that output for a more portable approach.

It then rebuilds the index file.

    def up_trigger(env, machine)

      # make our SSH config directory if we need it
      cfg_dir = ssh_config_dir
      return if !File.directory? cfg_dir

      # now dump the vagrant SSH config into a named file
      ssh_config = `bash -c 'vagrant ssh-config'`
      cfg_dir.join(machine.name.to_s + '.config').write("\n" + ssh_config)

      build_ssh_include_file(cfg_dir)
    end

The down trigger removes the appropriate SSH config file and rebuilds the index. So the host will disappear from your vscode remotes.

    def down_trigger(env, machine)
      cfg_dir = ssh_config_dir
      return if !File.directory? cfg_dir

      cfg_file = cfg_dir.join(machine.name.to_s + '.config')
      cfg_file.unlink if File.file? cfg_file
      build_ssh_include_file(cfg_dir)
    end

So you then include the master list in .ssh/config:

Include ~/.vagrant.d/mydir/ssh/include.config

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