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 proxy support #175

Merged
merged 1 commit into from
May 6, 2019
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
55 changes: 46 additions & 9 deletions build.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,22 @@ type Lifecycle interface {
}

type BuildOptions struct {
AppDir string // defaults to current working directory
Builder string // defaults to default builder on the client config
RunImage string // defaults to the best mirror from the builder image or pack config
Env map[string]string
Image string // required
Publish bool
NoPull bool
ClearCache bool
Buildpacks []string
AppDir string // defaults to current working directory
Builder string // defaults to default builder on the client config
RunImage string // defaults to the best mirror from the builder image or pack config
Env map[string]string
Image string // required
Publish bool
NoPull bool
ClearCache bool
Buildpacks []string
ProxyConfig *ProxyConfig // defaults to environment proxy vars
}

type ProxyConfig struct {
HTTPProxy string
HTTPSProxy string
NoProxy string
}

func (c *Client) Build(ctx context.Context, opts BuildOptions) error {
Expand All @@ -49,10 +56,13 @@ func (c *Client) Build(ctx context.Context, opts BuildOptions) error {
return errors.Wrapf(err, "invalid app dir '%s'", opts.AppDir)
}

proxyConfig := c.processProxyConfig(opts.ProxyConfig)

builderRef, err := c.processBuilderName(opts.Builder)
if err != nil {
return errors.Wrapf(err, "invalid builder '%s'", opts.Builder)
}

rawBuilderImage, err := c.imageFetcher.Fetch(ctx, builderRef.Name(), true, !opts.NoPull)
if err != nil {
return errors.Wrapf(err, "failed to fetch builder image '%s'", builderRef.Name())
Expand Down Expand Up @@ -87,6 +97,9 @@ func (c *Client) Build(ctx context.Context, opts BuildOptions) error {
RunImage: runImage,
ClearCache: opts.ClearCache,
Publish: opts.Publish,
HTTPProxy: proxyConfig.HTTPProxy,
HTTPSProxy: proxyConfig.HTTPSProxy,
NoProxy: proxyConfig.NoProxy,
})
}

Expand Down Expand Up @@ -197,6 +210,30 @@ func (c *Client) processAppDir(appDir string) (string, error) {
return resolvedAppDir, nil
}

func (c *Client) processProxyConfig(config *ProxyConfig) ProxyConfig {
var (
httpProxy, httpsProxy, noProxy string
ok bool
)
if config != nil {
return *config
}
if httpProxy, ok = os.LookupEnv("HTTP_PROXY"); !ok {
httpProxy = os.Getenv("http_proxy")
}
if httpsProxy, ok = os.LookupEnv("HTTPS_PROXY"); !ok {
httpsProxy = os.Getenv("https_proxy")
}
if noProxy, ok = os.LookupEnv("NO_PROXY"); !ok {
noProxy = os.Getenv("no_proxy")
}
return ProxyConfig{
HTTPProxy: httpProxy,
HTTPSProxy: httpsProxy,
NoProxy: noProxy,
}
}

func (c *Client) processBuildpacks(buildpacks []string) ([]buildpack.Buildpack, builder.GroupMetadata, error) {
group := builder.GroupMetadata{Buildpacks: []builder.GroupBuildpack{}}
var bps []buildpack.Buildpack
Expand Down
37 changes: 18 additions & 19 deletions build/lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,22 @@ import (
"github.com/pkg/errors"

"github.com/buildpack/pack/builder"
"github.com/buildpack/pack/buildpack"
"github.com/buildpack/pack/cache"
"github.com/buildpack/pack/logging"
"github.com/buildpack/pack/style"
)

type Lifecycle struct {
Builder *builder.Builder
builder *builder.Builder
logger *logging.Logger
docker *client.Client
LayersVolume string
AppVolume string
appDir string
appOnce *sync.Once
}

type LifecycleConfig struct {
BuilderImage string
Logger *logging.Logger
Env map[string]string
Buildpacks []string
AppDir string
BPFetcher *buildpack.Fetcher
httpProxy string
httpsProxy string
noProxy string
LayersVolume string
AppVolume string
}

func init() {
Expand All @@ -51,6 +44,9 @@ type LifecycleOptions struct {
RunImage string
ClearCache bool
Publish bool
HTTPProxy string
HTTPSProxy string
NoProxy string
}

func (l *Lifecycle) Execute(ctx context.Context, opts LifecycleOptions) error {
Expand All @@ -62,12 +58,12 @@ func (l *Lifecycle) Execute(ctx context.Context, opts LifecycleOptions) error {
}
l.logger.Verbose("Cache image %s cleared", style.Symbol(cacheImage.Image()))
}
l.Setup(opts.AppDir, opts.Builder)
l.Setup(opts)
defer l.Cleanup()

if lifecycleVersion := l.Builder.GetLifecycleVersion(); lifecycleVersion == "" {
if lifecycleVersion := l.builder.GetLifecycleVersion(); lifecycleVersion == "" {
l.logger.Verbose("Warning: lifecycle version unknown")
}else {
} else {
l.logger.Verbose("Executing lifecycle version %s", style.Symbol(lifecycleVersion))
}

Expand Down Expand Up @@ -109,12 +105,15 @@ func (l *Lifecycle) Execute(ctx context.Context, opts LifecycleOptions) error {
return nil
}

func (l *Lifecycle) Setup(appDir string, builder *builder.Builder) {
func (l *Lifecycle) Setup(opts LifecycleOptions) {
l.LayersVolume = "pack-layers-" + randString(10)
l.AppVolume = "pack-app-" + randString(10)
l.appDir = appDir
l.appDir = opts.AppDir
l.appOnce = &sync.Once{}
l.Builder = builder
l.builder = opts.Builder
l.httpProxy = opts.HTTPProxy
l.httpsProxy = opts.HTTPSProxy
l.noProxy = opts.NoProxy
}

func (l *Lifecycle) Cleanup() error {
Expand Down
20 changes: 19 additions & 1 deletion build/lifecycle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,13 @@ func testLifecycle(t *testing.T, when spec.G, it spec.S) {
h.AssertNil(t, err)
bldr, err := builder.GetBuilder(builderImage)
h.AssertNil(t, err)
subject.Setup(filepath.Join("testdata", "fake-app"), bldr)
subject.Setup(build.LifecycleOptions{
AppDir: filepath.Join("testdata", "fake-app"),
Builder: bldr,
HTTPProxy: "some-http-proxy",
HTTPSProxy: "some-https-proxy",
NoProxy: "some-no-proxy",
})
})

it.After(func() {
Expand Down Expand Up @@ -129,6 +135,18 @@ func testLifecycle(t *testing.T, when spec.G, it spec.S) {
h.AssertContains(t, outBuf.String(), "failed to read file")
})

it("sets the proxy vars in the container", func() {
phase, err := subject.NewPhase(
"phase",
build.WithArgs("proxy"),
)
h.AssertNil(t, err)
assertRunSucceeds(t, phase, &outBuf, &errBuf)
h.AssertContains(t, outBuf.String(), "HTTP_PROXY=some-http-proxy")
h.AssertContains(t, outBuf.String(), "HTTPS_PROXY=some-https-proxy")
h.AssertContains(t, outBuf.String(), "NO_PROXY=some-no-proxy")
})

when("#WithArgs", func() {
it("runs the subject phase with args", func() {
phase, err := subject.NewPhase("phase", build.WithArgs("some", "args"))
Expand Down
19 changes: 15 additions & 4 deletions build/phase.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type Phase struct {

func (l *Lifecycle) NewPhase(name string, ops ...func(*Phase) (*Phase, error)) (*Phase, error) {
ctrConf := &dcontainer.Config{
Image: l.Builder.Name(),
Image: l.builder.Name(),
Labels: map[string]string{"author": "pack"},
}
hostConf := &dcontainer.HostConfig{
Expand All @@ -47,11 +47,22 @@ func (l *Lifecycle) NewPhase(name string, ops ...func(*Phase) (*Phase, error)) (
name: name,
docker: l.docker,
logger: l.logger,
uid: l.Builder.UID,
gid: l.Builder.GID,
uid: l.builder.UID,
gid: l.builder.GID,
appDir: l.appDir,
appOnce: l.appOnce,
}

if l.httpProxy != "" {
phase.ctrConf.Env = append(phase.ctrConf.Env, "HTTP_PROXY="+l.httpProxy)
}
if l.httpsProxy != "" {
phase.ctrConf.Env = append(phase.ctrConf.Env, "HTTPS_PROXY="+l.httpsProxy)
}
if l.noProxy != "" {
phase.ctrConf.Env = append(phase.ctrConf.Env, "NO_PROXY="+l.noProxy)
}

var err error
for _, op := range ops {
phase, err = op(phase)
Expand Down Expand Up @@ -83,7 +94,7 @@ func WithRegistryAccess(repos ...string) func(*Phase) (*Phase, error) {
if err != nil {
return nil, err
}
phase.ctrConf.Env = []string{fmt.Sprintf(`CNB_REGISTRY_AUTH=%s`, authHeader)}
phase.ctrConf.Env = append(phase.ctrConf.Env, fmt.Sprintf(`CNB_REGISTRY_AUTH=%s`, authHeader))
phase.hostConf.NetworkMode = "host"
return phase, nil
}
Expand Down
10 changes: 10 additions & 0 deletions build/testdata/fake-lifecycle/phase.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ func main() {
if len(os.Args) > 1 && os.Args[1] == "buildpacks" {
testBuildpacks()
}
if len(os.Args) > 1 && os.Args[1] == "proxy" {
testProxy()
}
}

func testWrite(filename, contents string) {
Expand Down Expand Up @@ -128,6 +131,13 @@ func testBuildpacks() {
readDir("/buildpacks")
}

func testProxy() {
fmt.Println("proxy test")
fmt.Println("HTTP_PROXY="+os.Getenv("HTTP_PROXY"))
fmt.Println("HTTPS_PROXY="+os.Getenv("HTTPS_PROXY"))
fmt.Println("NO_PROXY="+os.Getenv("NO_PROXY"))
}

func readDir(dir string) {
fis, err := ioutil.ReadDir(dir)
if err != nil {
Expand Down
Loading