Skip to content

Commit

Permalink
Make docker engine port configurable
Browse files Browse the repository at this point in the history
Introduced -engine-port flag in create subcommand
Extended drivers interface with a GetPort() method
Updated all drivers with the new interface
Updated provisioning to use GetPort() rather than parse GetURL() for the port
Made driver options for setting the engine port emit a useful error message
Fixes docker#3361

Signed-off-by: Wouter Dullaert <[email protected]>
(cherry picked from commit edad5f7)
  • Loading branch information
wdullaer authored and afbjorklund committed Dec 3, 2017
1 parent 49dfaa7 commit 82ba182
Show file tree
Hide file tree
Showing 37 changed files with 321 additions and 98 deletions.
7 changes: 7 additions & 0 deletions commands/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ var (
Usage: "Specify environment variables to set in the engine",
Value: &cli.StringSlice{},
},
cli.IntFlag{
Name: "engine-port",
Usage: "Specify the port number that the engine will listen on",
Value: engine.DefaultPort,
EnvVar: "ENGINE_PORT_NUMBER",
},
cli.BoolFlag{
Name: "swarm",
Usage: "Configure Machine to join a Swarm cluster",
Expand Down Expand Up @@ -157,6 +163,7 @@ func cmdCreateInner(c CommandLine, api libmachine.API) error {
rawDriver, err := json.Marshal(&drivers.BaseDriver{
MachineName: name,
StorePath: c.GlobalString("storage-path"),
PortNumber: c.Int("engine-port"),
})
if err != nil {
return fmt.Errorf("Error attempting to marshal bare driver data: %s", err)
Expand Down
1 change: 1 addition & 0 deletions commands/ls_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ func TestGetHostListItems(t *testing.T) {
Driver: &fakedriver.Driver{
MockState: state.Running,
MockIP: "active.host.com",
MockPort: 2376,
},
},
{
Expand Down
1 change: 1 addition & 0 deletions commands/url_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func TestCmdURL(t *testing.T) {
Driver: &fakedriver.Driver{
MockState: state.Running,
MockIP: "120.0.0.1",
MockPort: 2376,
},
},
},
Expand Down
9 changes: 4 additions & 5 deletions drivers/amazonec2/amazonec2.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ const (
)

var (
dockerPort = 2376
swarmPort = 3376
errorNoPrivateSSHKey = errors.New("using --amazonec2-keypair-name also requires --amazonec2-ssh-keypath")
errorMissingCredentials = errors.New("amazonec2 driver requires AWS credentials configured with the --amazonec2-access-key and --amazonec2-secret-key options, environment variables, ~/.aws/credentials, or an instance role")
Expand Down Expand Up @@ -759,7 +758,7 @@ func (d *Driver) GetURL() (string, error) {
return "", nil
}

return fmt.Sprintf("tcp://%s", net.JoinHostPort(ip, strconv.Itoa(dockerPort))), nil
return fmt.Sprintf("tcp://%s", net.JoinHostPort(ip, strconv.Itoa(d.GetPort()))), nil
}

func (d *Driver) GetIP() (string, error) {
Expand Down Expand Up @@ -1128,11 +1127,11 @@ func (d *Driver) configureSecurityGroupPermissions(group *ec2.SecurityGroup) ([]
})
}

if !hasPorts[fmt.Sprintf("%d/tcp", dockerPort)] {
if !hasPorts[fmt.Sprintf("%d/tcp", d.GetPort())] {
perms = append(perms, &ec2.IpPermission{
IpProtocol: aws.String("tcp"),
FromPort: aws.Int64(int64(dockerPort)),
ToPort: aws.Int64(int64(dockerPort)),
FromPort: aws.Int64(int64(d.GetPort())),
ToPort: aws.Int64(int64(d.GetPort())),
IpRanges: []*ec2.IpRange{{CidrIp: aws.String(ipRange)}},
})
}
Expand Down
40 changes: 20 additions & 20 deletions drivers/amazonec2/amazonec2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (

const (
testSSHPort = int64(22)
testDockerPort = int64(2376)
testDockerPort = int64(12345)
testSwarmPort = int64(3376)
)

Expand All @@ -32,7 +32,7 @@ var (
)

func TestConfigureSecurityGroupPermissionsEmpty(t *testing.T) {
driver := NewTestDriver()
driver := NewTestDriver(int(testDockerPort))

perms, err := driver.configureSecurityGroupPermissions(securityGroup)

Expand All @@ -41,7 +41,7 @@ func TestConfigureSecurityGroupPermissionsEmpty(t *testing.T) {
}

func TestConfigureSecurityGroupPermissionsSshOnly(t *testing.T) {
driver := NewTestDriver()
driver := NewTestDriver(int(testDockerPort))
group := securityGroup
group.IpPermissions = []*ec2.IpPermission{
{
Expand All @@ -59,7 +59,7 @@ func TestConfigureSecurityGroupPermissionsSshOnly(t *testing.T) {
}

func TestConfigureSecurityGroupPermissionsDockerOnly(t *testing.T) {
driver := NewTestDriver()
driver := NewTestDriver(int(testDockerPort))
group := securityGroup
group.IpPermissions = []*ec2.IpPermission{
{
Expand All @@ -77,7 +77,7 @@ func TestConfigureSecurityGroupPermissionsDockerOnly(t *testing.T) {
}

func TestConfigureSecurityGroupPermissionsDockerAndSsh(t *testing.T) {
driver := NewTestDriver()
driver := NewTestDriver(int(testDockerPort))
group := securityGroup
group.IpPermissions = []*ec2.IpPermission{
{
Expand All @@ -99,7 +99,7 @@ func TestConfigureSecurityGroupPermissionsDockerAndSsh(t *testing.T) {
}

func TestConfigureSecurityGroupPermissionsOpenPorts(t *testing.T) {
driver := NewTestDriver()
driver := NewTestDriver(int(testDockerPort))
driver.OpenPorts = []string{"8888/tcp", "8080/udp", "9090"}
perms, err := driver.configureSecurityGroupPermissions(&ec2.SecurityGroup{})

Expand All @@ -114,7 +114,7 @@ func TestConfigureSecurityGroupPermissionsOpenPorts(t *testing.T) {
}

func TestConfigureSecurityGroupPermissionsOpenPortsSkipExisting(t *testing.T) {
driver := NewTestDriver()
driver := NewTestDriver(int(testDockerPort))
group := securityGroup
group.IpPermissions = []*ec2.IpPermission{
{
Expand All @@ -137,7 +137,7 @@ func TestConfigureSecurityGroupPermissionsOpenPortsSkipExisting(t *testing.T) {
}

func TestConfigureSecurityGroupPermissionsInvalidOpenPorts(t *testing.T) {
driver := NewTestDriver()
driver := NewTestDriver(int(testDockerPort))
driver.OpenPorts = []string{"2222/tcp", "abc1"}
perms, err := driver.configureSecurityGroupPermissions(&ec2.SecurityGroup{})

Expand All @@ -146,7 +146,7 @@ func TestConfigureSecurityGroupPermissionsInvalidOpenPorts(t *testing.T) {
}

func TestConfigureSecurityGroupPermissionsWithSwarm(t *testing.T) {
driver := NewTestDriver()
driver := NewTestDriver(int(testDockerPort))
driver.SwarmMaster = true
group := securityGroup
group.IpPermissions = []*ec2.IpPermission{
Expand Down Expand Up @@ -219,7 +219,7 @@ func TestDefaultVPCIsMissing(t *testing.T) {
}

func TestGetRegionZoneForDefaultEndpoint(t *testing.T) {
driver := NewCustomTestDriver(&fakeEC2WithLogin{})
driver := NewCustomTestDriver(int(testDockerPort), &fakeEC2WithLogin{})
driver.awsCredentialsFactory = NewValidAwsCredentials
options := &commandstest.FakeFlagger{
Data: map[string]interface{}{
Expand All @@ -238,7 +238,7 @@ func TestGetRegionZoneForDefaultEndpoint(t *testing.T) {
}

func TestGetRegionZoneForCustomEndpoint(t *testing.T) {
driver := NewCustomTestDriver(&fakeEC2WithLogin{})
driver := NewCustomTestDriver(int(testDockerPort), &fakeEC2WithLogin{})
driver.awsCredentialsFactory = NewValidAwsCredentials
options := &commandstest.FakeFlagger{
Data: map[string]interface{}{
Expand Down Expand Up @@ -272,7 +272,7 @@ func TestDescribeAccountAttributeFails(t *testing.T) {
}

func TestAwsCredentialsAreRequired(t *testing.T) {
driver := NewTestDriver()
driver := NewTestDriver(int(testDockerPort))
driver.awsCredentialsFactory = NewErrorAwsCredentials

options := &commandstest.FakeFlagger{
Expand All @@ -288,7 +288,7 @@ func TestAwsCredentialsAreRequired(t *testing.T) {
}

func TestValidAwsCredentialsAreAccepted(t *testing.T) {
driver := NewCustomTestDriver(&fakeEC2WithLogin{})
driver := NewCustomTestDriver(int(testDockerPort), &fakeEC2WithLogin{})
driver.awsCredentialsFactory = NewValidAwsCredentials
options := &commandstest.FakeFlagger{
Data: map[string]interface{}{
Expand All @@ -303,7 +303,7 @@ func TestValidAwsCredentialsAreAccepted(t *testing.T) {
}

func TestEndpointIsMandatoryWhenSSLDisabled(t *testing.T) {
driver := NewTestDriver()
driver := NewTestDriver(int(testDockerPort))
driver.awsCredentialsFactory = NewValidAwsCredentials
options := &commandstest.FakeFlagger{
Data: map[string]interface{}{
Expand Down Expand Up @@ -402,7 +402,7 @@ func ipPermission(port int64) *ec2.IpPermission {
func TestConfigureSecurityGroupsEmpty(t *testing.T) {
recorder := fakeEC2SecurityGroupTestRecorder{}

driver := NewCustomTestDriver(&recorder)
driver := NewCustomTestDriver(int(testDockerPort), &recorder)
err := driver.configureSecurityGroups([]string{})

assert.Nil(t, err)
Expand Down Expand Up @@ -457,7 +457,7 @@ func TestConfigureSecurityGroupsMixed(t *testing.T) {
}).Return(
&ec2.AuthorizeSecurityGroupIngressOutput{}, nil)

driver := NewCustomTestDriver(&recorder)
driver := NewCustomTestDriver(int(testDockerPort), &recorder)
err := driver.configureSecurityGroups(groups)

assert.Nil(t, err)
Expand All @@ -472,15 +472,15 @@ func TestConfigureSecurityGroupsErrLookupExist(t *testing.T) {
recorder.On("DescribeSecurityGroups", mock.MatchedBy(matchGroupLookup(groups))).Return(
nil, lookupExistErr)

driver := NewCustomTestDriver(&recorder)
driver := NewCustomTestDriver(int(testDockerPort), &recorder)
err := driver.configureSecurityGroups(groups)

assert.Exactly(t, lookupExistErr, err)
recorder.AssertExpectations(t)
}

func TestBase64UserDataIsEmptyIfNoFileProvided(t *testing.T) {
driver := NewTestDriver()
driver := NewTestDriver(int(testDockerPort))

userdata, err := driver.Base64UserData()

Expand All @@ -495,7 +495,7 @@ func TestBase64UserDataGeneratesErrorIfFileNotFound(t *testing.T) {
defer os.RemoveAll(dir)
userdata_path := filepath.Join(dir, "does-not-exist.yml")

driver := NewTestDriver()
driver := NewTestDriver(int(testDockerPort))
driver.UserDataFile = userdata_path

_, ud_err := driver.Base64UserData()
Expand All @@ -516,7 +516,7 @@ func TestBase64UserDataIsCorrectWhenFileProvided(t *testing.T) {
err = ioutil.WriteFile(userdata_path, content, 0666)
assert.NoError(t, err, "Unable to create temporary userdata file.")

driver := NewTestDriver()
driver := NewTestDriver(int(testDockerPort))
driver.UserDataFile = userdata_path

userdata, ud_err := driver.Base64UserData()
Expand Down
6 changes: 4 additions & 2 deletions drivers/amazonec2/stub_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,18 @@ func (f *fakeEC2SecurityGroupTestRecorder) AuthorizeSecurityGroupIngress(input *
return value, err
}

func NewTestDriver() *Driver {
func NewTestDriver(dockerPort int) *Driver {
driver := NewDriver("machineFoo", "path")
driver.PortNumber = dockerPort
driver.clientFactory = func() Ec2Client {
return &fakeEC2{}
}
return driver
}

func NewCustomTestDriver(ec2Client Ec2Client) *Driver {
func NewCustomTestDriver(dockerPort int, ec2Client Ec2Client) *Driver {
driver := NewDriver("machineFoo", "path")
driver.PortNumber = dockerPort
driver.clientFactory = func() Ec2Client {
return ec2Client
}
Expand Down
22 changes: 12 additions & 10 deletions drivers/azure/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net"
"net/url"
"os"
"strconv"

"github.com/docker/machine/drivers/azure/azureutil"
"github.com/docker/machine/libmachine/drivers"
Expand All @@ -24,7 +25,6 @@ const (
defaultAzureSize = "Standard_A2"
defaultAzureLocation = "westus"
defaultSSHUser = "docker-user" // 'root' not allowed on Azure
defaultDockerPort = 2376
defaultAzureImage = "canonical:UbuntuServer:16.04.0-LTS:latest"
defaultAzureVNet = "docker-machine-vnet"
defaultAzureSubnet = "docker-machine"
Expand Down Expand Up @@ -74,7 +74,6 @@ type Driver struct {
SubscriptionID string
ResourceGroup string

DockerPort int
Location string
Size string
Image string
Expand Down Expand Up @@ -139,12 +138,6 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag {
EnvVar: "AZURE_SSH_USER",
Value: defaultSSHUser,
},
mcnflag.IntFlag{
Name: flAzureDockerPort,
Usage: "Port number for Docker engine",
EnvVar: "AZURE_DOCKER_PORT",
Value: defaultDockerPort,
},
mcnflag.StringFlag{
Name: flAzureLocation,
Usage: "Azure region to create the virtual machine",
Expand Down Expand Up @@ -233,6 +226,12 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag {
Usage: "Azure Service Principal Account password (optional, browser auth is used if not specified)",
EnvVar: "AZURE_CLIENT_SECRET",
},
// DEPRECATED: remove in a future version
mcnflag.IntFlag{
Name: flAzureDockerPort,
Usage: "Port number for Docker engine",
EnvVar: "AZURE_DOCKER_PORT",
},
}
}

Expand Down Expand Up @@ -273,7 +272,6 @@ func (d *Driver) SetConfigFromFlags(fl drivers.DriverOptions) error {
d.UsePrivateIP = fl.Bool(flAzureUsePrivateIP)
d.NoPublicIP = fl.Bool(flAzureNoPublicIP)
d.StaticPublicIP = fl.Bool(flAzureStaticPublicIP)
d.DockerPort = fl.Int(flAzureDockerPort)
d.DNSLabel = fl.String(flAzureDNSLabel)
d.CustomDataFile = fl.String(flAzureCustomData)

Expand All @@ -284,6 +282,10 @@ func (d *Driver) SetConfigFromFlags(fl drivers.DriverOptions) error {
d.BaseDriver.SSHPort = sshPort
d.SetSwarmConfigFromFlags(fl)

if fl.Int(flAzureDockerPort) != 0 {
return fmt.Errorf("-%s has been deprecated in favor of: -engine-port", flAzureDockerPort)
}

log.Debug("Set configuration from flags.")
return nil
}
Expand Down Expand Up @@ -473,7 +475,7 @@ func (d *Driver) GetURL() (string, error) {
}
u := (&url.URL{
Scheme: "tcp",
Host: net.JoinHostPort(ip, fmt.Sprintf("%d", d.DockerPort)),
Host: net.JoinHostPort(ip, strconv.Itoa(d.GetPort())),
}).String()
log.Debugf("Machine URL is resolved to: %s", u)
return u, nil
Expand Down
29 changes: 29 additions & 0 deletions drivers/azure/azure_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package azure

import (
"testing"

"github.com/docker/machine/libmachine/drivers"
"github.com/stretchr/testify/assert"
)

func TestGenericDockerPortDeprecationError(t *testing.T) {
driver := NewDriver("default", "path")

checkFlags := &drivers.CheckDriverOptions{
FlagsValues: map[string]interface{}{
"azure-subscription-id": "abcdef",
"azure-docker-port": 12345,
},
CreateFlags: driver.GetCreateFlags(),
}

err := driver.SetConfigFromFlags(checkFlags)

assert.EqualError(
t,
err,
"-azure-docker-port has been deprecated in favor of: -engine-port",
"SetConfigFromFlags should throw an error when generic-docker-port is set",
)
}
4 changes: 2 additions & 2 deletions drivers/azure/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,12 @@ func (d *Driver) getSecurityRules(extraPorts []string) (*[]network.SecurityRule,
}
}

log.Debugf("Docker port is configured as %d", d.DockerPort)
log.Debugf("Docker port is configured as %d", d.GetPort())

// Base ports to be opened for any machine
rl := []network.SecurityRule{
mkRule(100, "SSHAllowAny", "Allow ssh from public Internet", "*", fmt.Sprintf("%d", d.BaseDriver.SSHPort), network.TCP),
mkRule(300, "DockerAllowAny", "Allow docker engine access (TLS-protected)", "*", fmt.Sprintf("%d", d.DockerPort), network.TCP),
mkRule(300, "DockerAllowAny", "Allow docker engine access (TLS-protected)", "*", fmt.Sprintf("%d", d.GetPort()), network.TCP),
}

// Open swarm port if configured
Expand Down
Loading

0 comments on commit 82ba182

Please sign in to comment.