Adds a new -disable-host-node-id option to help when testing with containers.

Fixes #2877.
This commit is contained in:
James Phillips 2017-04-12 22:05:38 -07:00
parent 1b78e9e6b1
commit 20bf47d2b4
No known key found for this signature in database
GPG Key ID: 77183E682AC5FC11
6 changed files with 85 additions and 21 deletions

View File

@ -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 {

View File

@ -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)
@ -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)

View File

@ -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.")

View File

@ -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"`
@ -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
}

View File

@ -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)
@ -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)
}
@ -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,

View File

@ -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.
@ -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`.
@ -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