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

Add support for yum proxy configuration #4

Merged
merged 8 commits into from
Oct 29, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# 0.6.1 / _Unreleased_

- Add support for configuring Yum directly (not only via global env vars) ([GH-4][])

# 0.6.0 / 2013-10-15

Expand Down Expand Up @@ -63,6 +64,7 @@


[GH-2]: https://github.com/tmatilai/vagrant-proxyconf/issues/2 "Issue 2"
[GH-4]: https://github.com/tmatilai/vagrant-proxyconf/issues/4 "Issue 4"
[GH-5]: https://github.com/tmatilai/vagrant-proxyconf/issues/5 "Issue 5"
[GH-6]: https://github.com/tmatilai/vagrant-proxyconf/issues/6 "Issue 6"
[GH-7]: https://github.com/tmatilai/vagrant-proxyconf/issues/7 "Issue 7"
Expand Down
1 change: 1 addition & 0 deletions Guardfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
guard 'rspec' do
watch(%r{^spec/unit/.+_spec\.rb$})
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" }
watch(%r{^(resources/.+)\.}) { |m| "spec/unit/vagrant-proxyconf/#{m[1]}_spec.rb" }
watch('spec/spec_helper.rb') { "spec" }
end
58 changes: 47 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@

A [Vagrant](http://www.vagrantup.com/) plugin that configures the virtual machine to use specified proxies. This is useful for example in case you are behind a corporate proxy server, or you have a caching proxy (for example [polipo](https://github.com/tmatilai/polipo-box)).

At this state we support:
The plugin can set:

* Generic `http_proxy` etc. environment variables that many programs support
* APT proxy/cacher
* Setting default proxy configuration for all Chef provisioners
* generic `http_proxy` etc. environment variables that many programs support
* default proxy configuration for all Chef provisioners
* proxy configuration for Apt
* proxy configuration for Yum

## Quick start

Expand Down Expand Up @@ -86,7 +87,7 @@ end
#### Possible values

* If all keys are unset or `nil`, no configuration is written.
* A proxy should be specified in the form of _protocol://[user:pass@]host[:port]_.
* A proxy should be specified in the form of _http://[user:pass@]host:port_.
* Empty string (`""`) or `false` in any setting also force the configuration files to be written, but without configuration for that key. Can be used to clear the old configuration and/or override a global setting.

#### Environment variables
Expand All @@ -106,7 +107,7 @@ VAGRANT_HTTP_PROXY="http://proxy.example.com:8080" vagrant up

### Global `*_proxy` environment variables

Many programs (wget, curl, yum, etc.) can be configured to use proxies with `<protocol>_proxy` or `<PROTOCOL>_PROXY` environment variables. This configuration will be written to _/etc/profile.d/proxy.sh_ on the guest.
Many programs (wget, curl, yum, etc.) can be configured to use proxies with `http_proxy` or `HTTP_PROXY` etc. environment variables. This configuration will be written to _/etc/profile.d/proxy.sh_ on the guest.

Also sudo will be configured to preserve the variables. This requires that sudo in the VM is configured to support "sudoers.d", i.e. _/etc/sudoers_ contains line `#includedir /etc/sudoers.d`.

Expand All @@ -131,7 +132,7 @@ end
#### Possible values

* If all keys are unset or `nil`, no configuration is written.
* A proxy can be specified in the form of _protocol://[user:pass@]host[:port]_.
* A proxy can be specified in the form of _http://[user:pass@]host:port_.
* The values are used as specified, so you can use for example variables that will be evaluated by the shell on the VM.
* Empty string (`""`) or `false` in any setting also force the configuration file to be written, but without configuration for that key. Can be used to clear the old configuration and/or override a global setting.

Expand All @@ -158,7 +159,7 @@ Configures Apt to use the specified proxy settings. The configuration will be wr

```ruby
Vagrant.configure("2") do |config|
config.apt_proxy.http = "192.168.33.1:3142"
config.apt_proxy.http = "http://192.168.33.1:3142"
config.apt_proxy.https = "DIRECT"
# ... other stuff
end
Expand All @@ -172,9 +173,9 @@ end

#### Possible values

* If all keys are unset or `nil`, no configuration is written.
* A proxy can be specified in the form of _[http://][user:pass@]host[:port]_. So all but the _host_ part are optional. The default port is 3142 and protocol is the same as the key.
* Empty string (`""`) or `false` in any protocol also force the configuration file to be written, but without configuration for that protocol. Can be used to clear the old configuration and/or override a global setting.
* If all keys are unset or `nil`, no configuration is written or modified.
* A proxy can be specified in the form of _[http://][user:pass@]host[:port]_. So all but the _host_ part are optional. The default port is 3142 and scheme is the same as the key.
* Empty string (`""`) or `false` in any key also force the configuration file to be written, but without configuration for that scheme. Can be used to clear the old configuration and/or override a global setting.
* `"DIRECT"` can be used to specify that no proxy should be used. This is mostly useful for disabling proxy for HTTPS URIs when HTTP proxy is set (as Apt defaults to the latter).
* Please refer to [apt.conf(5)](http://manpages.debian.net/man/5/apt.conf) manual for more information.

Expand All @@ -196,6 +197,41 @@ VAGRANT_APT_HTTP_PROXY="proxy.example.com:8080" vagrant up

[apt-cacher-box](https://github.com/tmatilai/apt-cacher-box) gives an example for setting up apt-cacher proxy server in a Vagrant VM.

### Yum

Configures Yum to use the specified proxy settings. The configuration will be inserted to _/etc/yum.conf_ on the guest.

#### Example Vagrantfile

```ruby
Vagrant.configure("2") do |config|
config.yum_proxy.http = "http://192.168.33.1:3142"
# ... other stuff
end
```

#### Configuration keys

* `config.yum_proxy.http` - The proxy for yum

#### Possible values

* If the keys is unset or `nil`, the current configuration is not modified.
* A proxy can be specified in the form of _http://[user:pass@]host:port_.
* Empty string (`""`) or `false` disables the proxy from the configuration.

#### Environment variables

* `VAGRANT_YUM_HTTP_PROXY`

This also overrides the Vagrantfile configuration. To disable or remove the proxy use an empty value.

For example to spin up a VM, run:

```sh
VAGRANT_YUM_HTTP_PROXY="http://proxy.example.com:8123" vagrant up
```

## Related plugins and projects

* [apt-cacher-box](https://github.com/tmatilai/apt-cacher-box)<br/>
Expand Down
2 changes: 2 additions & 0 deletions lib/vagrant-proxyconf/action.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require_relative 'action/configure_apt_proxy'
require_relative 'action/configure_chef_proxy'
require_relative 'action/configure_env_proxy'
require_relative 'action/configure_yum_proxy'
require_relative 'action/only_once'

module VagrantPlugins
Expand All @@ -24,6 +25,7 @@ def self.config_actions
builder.use ConfigureAptProxy
builder.use ConfigureChefProxy
builder.use ConfigureEnvProxy
builder.use ConfigureYumProxy
end
end
end
Expand Down
43 changes: 43 additions & 0 deletions lib/vagrant-proxyconf/action/configure_yum_proxy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
require_relative 'base'
require_relative '../resource'
require_relative '../userinfo_uri'

module VagrantPlugins
module ProxyConf
class Action
# Action for configuring Yum on the guest
class ConfigureYumProxy < Base
def config_name
'yum_proxy'
end

private

def configure_machine(machine, config)
tmp = "/tmp/vagrant-proxyconf"
path = config_path(machine)

machine.communicate.tap do |comm|
comm.upload(ProxyConf.resource("yum_config.awk"), tmp)
comm.sudo("touch #{path}")
comm.sudo("gawk -f #{tmp} #{proxy_params(config)} #{path} > #{path}.new")
comm.sudo("chmod 0644 #{path}.new")
comm.sudo("chown root:root #{path}.new")
comm.sudo("mv #{path}.new #{path}")
comm.sudo("rm #{tmp}")
end
end

def proxy_params(config)
u = UserinfoURI.new(config.http)
"-v proxy=#{escape(u.uri)} -v user=#{escape(u.user)} -v pass=#{escape(u.pass)}"
end

# @param value [String, nil] the string to escape for shell usage
def escape(value)
value.to_s.shellescape
end
end
end
end
end
15 changes: 15 additions & 0 deletions lib/vagrant-proxyconf/cap/redhat/yum_proxy_conf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module VagrantPlugins
module ProxyConf
module Cap
module Redhat
# Capability for Yum proxy configuration
module YumProxyConf
# @return [String] the path to the configuration file
def self.yum_proxy_conf(machine)
'/etc/yum.conf'
end
end
end
end
end
end
19 changes: 19 additions & 0 deletions lib/vagrant-proxyconf/config/yum_proxy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require 'vagrant'
require_relative 'key_mixin'

module VagrantPlugins
module ProxyConf
module Config
# Proxy configuration for Yum
#
# @!parse class YumProxy < Vagrant::Plugin::V2::Config; end
class YumProxy < Vagrant.plugin('2', :config)
include KeyMixin
# @!parse extend KeyMixin::ClassMethods

# @return [String] the HTTP proxy
key :http, env_var: 'VAGRANT_YUM_HTTP_PROXY'
end
end
end
end
10 changes: 10 additions & 0 deletions lib/vagrant-proxyconf/plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ def self.load_optional_dependencies
Config::Proxy
end

config 'yum_proxy' do
require_relative 'config/yum_proxy'
Config::YumProxy
end

guest_capability 'debian', 'apt_proxy_conf' do
require_relative 'cap/debian/apt_proxy_conf'
Cap::Debian::AptProxyConf
Expand All @@ -77,6 +82,11 @@ def self.load_optional_dependencies
Cap::Linux::EnvProxyConf
end

guest_capability 'redhat', 'yum_proxy_conf' do
require_relative 'cap/redhat/yum_proxy_conf'
Cap::Redhat::YumProxyConf
end

action_hook 'proxyconf_configure' do |hook|
require_relative 'action'

Expand Down
17 changes: 17 additions & 0 deletions lib/vagrant-proxyconf/resource.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module VagrantPlugins
# Base module for Vagrant Proxyconf plugin
module ProxyConf
# @param name [String] the resource file name
# @return [String] the absolute path to the resource file
def self.resource(name)
File.join(resource_root, name)
end

private

# @return [String] the absolute åath to the resource directory
def self.resource_root
File.expand_path('../../../resources', __FILE__)
end
end
end
8 changes: 8 additions & 0 deletions locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ en:
configuring: |-
Configuring proxy environment variables...

yum_proxy:
not_enabled: |-
yum_proxy not enabled or configured
not_supported: |-
Skipping Yum proxy config as the machine does not support it
configuring: |-
Configuring proxy for Yum...

errors:
vagrant_version: |-
vagrant-proxyconf plugin requires Vagrant %{min_version} or newer
65 changes: 65 additions & 0 deletions resources/yum_config.awk
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env gawk
#
# Adds or modifies proxy configuration for Yum
#
# Usage:
# yum_config.awk -v proxy=http://proxy:1234 -v user=foo -v pass=bar /etc/yum.comf
#
# License: MIT
# Copyright (c) 2013 Teemu Matilainen <teemu.matilainen@iki.fi>
#

BEGIN {
FS = OFS = "="

# [main] section:
# 0: not seen yet
# 1: inside of it
# 2: already on another section
main = 0

conf["proxy"] = (proxy ? proxy : "_none_")
conf["proxy_username"] = (proxy ? user : "")
conf["proxy_password"] = (proxy ? pass : "")
}

# Section headers
/^\[.*\]$/ {
if ($0 == "[main]") {
# entering [main] section
main = 1
} else if (main == 1) {
# [main] section ended
print_proxy_conf()
main = 2
}
}

# Old configuration
$1 ~ /^proxy(_username|_password)?$/ {
if (main == 1) {
$2 = conf[$1]
seen[$1] = 1
}
}

# Print every line by default
{ print $0 }

# Print missing configuration if needed
END {
if (main == 0) print "[main]"
if (main < 2) print_proxy_conf()
}

# Prints proxy* configuration not seen yet
function print_proxy_conf() {
print_key("proxy")
print_key("proxy_username")
print_key("proxy_password")
}

# Prints a proxy*=<value> line
function print_key(key) {
if (!seen[key]) print key, conf[key]
}
Empty file added spec/unit/fixtures/empty
Empty file.
4 changes: 4 additions & 0 deletions spec/unit/fixtures/yum_only_disabled_proxy.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[main]
proxy=_none_
proxy_username=
proxy_password=
25 changes: 25 additions & 0 deletions spec/unit/fixtures/yum_only_main.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[main]
cachedir=/var/cache/yum/$basearch/$releasever
keepcache=0
debuglevel=2
logfile=/var/log/yum.log
exactarch=1
obsoletes=1
gpgcheck=1
plugins=1
installonly_limit=5
bugtracker_url=http://bugs.centos.org/set_project.php?project_id=16&ref=http://bugs.centos.org/bug_report_page.php?category=yum
distroverpkg=centos-release

# This is the default, if you make this bigger yum won't see if the metadata
# is newer on the remote and so you'll "gain" the bandwidth of not having to
# download the new metadata and "pay" for it by yum not having correct
# information.
# It is esp. important, to have correct metadata, for distributions like
# Fedora which don't keep old packages around. If you don't like this checking
# interupting your command line usage, it's much better to have something
# manually check the metadata once an hour (yum-updatesd will do this).
# metadata_expire=90m

# PUT YOUR REPOS HERE OR IN separate files named file.repo
# in /etc/yum.repos.d
Loading