Skip to content

Commit

Permalink
Adds a new -disable-host-node-id option to help when testing with con…
Browse files Browse the repository at this point in the history
…tainers.

Fixes #2877.
  • Loading branch information
slackpad committed Apr 13, 2017
1 parent 0b96666 commit fa04c24
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 21 deletions.
5 changes: 5 additions & 0 deletions command/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,11 @@ func (a *Agent) makeRandomID() (string, error) {
// high for us if this changes, so we will persist it either way. This will let
// gopsutil change implementations without affecting in-place upgrades of nodes.
func (a *Agent) makeNodeID() (string, error) {
// If they've disabled host-based IDs then just make a random one.
if a.config.DisableHostNodeID {
return a.makeRandomID()
}

// Try to get a stable ID associated with the host itself.
info, err := host.Info()
if err != nil {
Expand Down
38 changes: 37 additions & 1 deletion command/agent/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ func TestAgent_ReconnectConfigSettings(t *testing.T) {
}()
}

func TestAgent_NodeID(t *testing.T) {
func TestAgent_setupNodeID(t *testing.T) {
c := nextConfig()
c.NodeID = ""
dir, agent := makeAgent(t, c)
Expand Down Expand Up @@ -384,6 +384,42 @@ func TestAgent_NodeID(t *testing.T) {
}
}

func TestAgent_makeNodeID(t *testing.T) {
c := nextConfig()
c.NodeID = ""
dir, agent := makeAgent(t, c)
defer os.RemoveAll(dir)
defer agent.Shutdown()

// We should get a valid host-based ID initially.
id, err := agent.makeNodeID()
if err != nil {
t.Fatalf("err: %v", err)
}
if _, err := uuid.ParseUUID(string(id)); err != nil {
t.Fatalf("err: %v", err)
}

// Calling again should yield the same ID since it's host-based.
another, err := agent.makeNodeID()
if err != nil {
t.Fatalf("err: %v", err)
}
if id != another {
t.Fatalf("bad: %s vs %s", id, another)
}

// Turn off host-based IDs and try again. We should get a random ID.
agent.config.DisableHostNodeID = true
another, err = agent.makeNodeID()
if err != nil {
t.Fatalf("err: %v", err)
}
if id == another {
t.Fatalf("bad: %s vs %s", id, another)
}
}

func TestAgent_AddService(t *testing.T) {
dir, agent := makeAgent(t, nextConfig())
defer os.RemoveAll(dir)
Expand Down
4 changes: 4 additions & 0 deletions command/agent/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ func (c *Command) readConfig() *Config {
f.StringVar((*string)(&cmdConfig.NodeID), "node-id", "",
"A unique ID for this node across space and time. Defaults to a randomly-generated ID"+
" that persists in the data-dir.")
f.BoolVar(&cmdConfig.DisableHostNodeID, "disable-host-node-id", false,
"Setting this to true will prevent Consul from using information from the"+
" host to generate a node ID, and will cause Consul to generate a"+
" random node ID instead.")
f.StringVar(&dcDeprecated, "dc", "", "Datacenter of the agent (deprecated: use 'datacenter' instead).")
f.StringVar(&cmdConfig.Datacenter, "datacenter", "", "Datacenter of the agent.")
f.StringVar(&cmdConfig.DataDir, "data-dir", "", "Path to a data directory to store agent state.")
Expand Down
8 changes: 8 additions & 0 deletions command/agent/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,11 @@ type Config struct {
// to a randomly-generated ID that persists in the data-dir.
NodeID types.NodeID `mapstructure:"node_id"`

// DisableHostNodeID will prevent Consul from using information from the
// host to generate a node ID, and will cause Consul to generate a
// random ID instead.
DisableHostNodeID bool `mapstructure:"disable_host_node_id"`

// Node name is the name we use to advertise. Defaults to hostname.
NodeName string `mapstructure:"node_name"`

Expand Down Expand Up @@ -1371,6 +1376,9 @@ func MergeConfig(a, b *Config) *Config {
if b.NodeID != "" {
result.NodeID = b.NodeID
}
if b.DisableHostNodeID == true {
result.DisableHostNodeID = b.DisableHostNodeID
}
if b.NodeName != "" {
result.NodeName = b.NodeName
}
Expand Down
25 changes: 15 additions & 10 deletions command/agent/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ func TestDecodeConfig(t *testing.T) {
t.Fatalf("bad: %#v", config)
}

// Without a protocol
input = `{"node_id": "bar", "node_name": "foo", "datacenter": "dc2"}`
// Node info
input = `{"node_id": "bar", "disable_host_node_id": true, "node_name": "foo", "datacenter": "dc2"}`
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
if err != nil {
t.Fatalf("err: %s", err)
Expand All @@ -74,6 +74,10 @@ func TestDecodeConfig(t *testing.T) {
t.Fatalf("bad: %#v", config)
}

if config.DisableHostNodeID != true {
t.Fatalf("bad: %#v", config)
}

if config.Datacenter != "dc2" {
t.Fatalf("bad: %#v", config)
}
Expand Down Expand Up @@ -1652,14 +1656,15 @@ func TestMergeConfig(t *testing.T) {
UDPAnswerLimit: 4,
RecursorTimeout: 30 * time.Second,
},
Domain: "other",
LogLevel: "info",
NodeID: "bar",
NodeName: "baz",
ClientAddr: "127.0.0.2",
BindAddr: "127.0.0.2",
AdvertiseAddr: "127.0.0.2",
AdvertiseAddrWan: "127.0.0.2",
Domain: "other",
LogLevel: "info",
NodeID: "bar",
DisableHostNodeID: true,
NodeName: "baz",
ClientAddr: "127.0.0.2",
BindAddr: "127.0.0.2",
AdvertiseAddr: "127.0.0.2",
AdvertiseAddrWan: "127.0.0.2",
Ports: PortConfig{
DNS: 1,
HTTP: 2,
Expand Down
26 changes: 16 additions & 10 deletions website/source/docs/agent/options.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -151,17 +151,22 @@ will exit with an error at startup.
the use of filesystem locking, meaning some types of mounted folders (e.g. VirtualBox
shared folders) may not be suitable.

* <a name="_datacenter"></a><a href="#_datacenter">`-datacenter`</a> - This flag controls the datacenter in
which the agent is running. If not provided,
it defaults to "dc1". Consul has first-class support for multiple datacenters, but
it relies on proper configuration. Nodes in the same datacenter should be on a single
LAN.

* <a name="_dev"></a><a href="#_dev">`-dev`</a> - Enable development server
mode. This is useful for quickly starting a Consul agent with all persistence
options turned off, enabling an in-memory server which can be used for rapid
prototyping or developing against the API. This mode is **not** intended for
production use as it does not write any data to disk.

* <a name="_datacenter"></a><a href="#_datacenter">`-datacenter`</a> - This flag controls the datacenter in
which the agent is running. If not provided,
it defaults to "dc1". Consul has first-class support for multiple datacenters, but
it relies on proper configuration. Nodes in the same datacenter should be on a single
LAN.
* <a name="_disable_host_node_id"></a><a href="#_disable_host_node_id">`-disable-host-node-id`</a> - Setting
this to true will prevent Consul from using information from the host to generate a deterministic node ID,
and will instead generate a random node ID which will be persisted in the data directory. This is useful
when running multiple Consul agents on the same host for testing. This defaults to false.

* <a name="_dns_port"></a><a href="#_dns_port">`-dns-port`</a> - the DNS port to listen on.
This overrides the default port 8600. This is available in Consul 0.7 and later.
Expand Down Expand Up @@ -295,11 +300,9 @@ will exit with an error at startup.
changes. This must be in the form of a hex string, 36 characters long, such as
`adf4238a-882b-9ddc-4a9d-5b6758e4159e`. If this isn't supplied, which is the most common case, then
the agent will generate an identifier at startup and persist it in the <a href="#_data_dir">data directory</a>
so that it will remain the same across agent restarts. This is currently only exposed via
<a href="/api/agent.html#agent_self">/v1/agent/self</a>,
<a href="/api/catalog.html">/v1/catalog</a>, and
<a href="/api/health.html">/v1/health</a> endpoints, but future versions of
Consul will use this to better manage cluster changes, especially for Consul servers.
so that it will remain the same across agent restarts. Information from the host will be used to
generate a deterministic node ID if possible, unless [`-disable-host-node-id`](#_disable_host_node_id) is
set to true.

* <a name="_node_meta"></a><a href="#_node_meta">`-node-meta`</a> - Available in Consul 0.7.3 and later,
this specifies an arbitrary metadata key/value pair to associate with the node, of the form `key:value`.
Expand Down Expand Up @@ -636,6 +639,9 @@ Consul will not enable TLS for the HTTP API unless the `https` port has been ass
`disable_anonymous_signature`</a> Disables providing an anonymous signature for de-duplication
with the update check. See [`disable_update_check`](#disable_update_check).

* <a name="disable_host_node_id"></a><a href="#disable_host_node_id">`disable_host_node_id`</a>
Equivalent to the [`-disable-host-node-id` command-line flag](#_disable_host_node_id).

* <a name="disable_remote_exec"></a><a href="#disable_remote_exec">`disable_remote_exec`</a>
Disables support for remote execution. When set to true, the agent will ignore any incoming
remote exec requests. In versions of Consul prior to 0.8, this defaulted to false. In Consul
Expand Down

0 comments on commit fa04c24

Please sign in to comment.