Make executor hostname configurable

The executor needs to know its hostname as it embeds it into the
finger url. In some environments it cannot correctly determine its own
hostname so the finger url (and thus live log streaming) would not
work. Making the hostname configurable can solve this easily in such
environments.

Change-Id: Ifeb639b4499d737e9045508c4f66aefa950effa6
diff --git a/doc/source/admin/components.rst b/doc/source/admin/components.rst
index 99817f7..b20aba7 100644
--- a/doc/source/admin/components.rst
+++ b/doc/source/admin/components.rst
@@ -522,6 +522,15 @@
       The executor will observe system load and determine whether
       to accept more jobs every 30 seconds.
 
+   .. attr:: hostname
+      :default: hostname of the server
+
+      The executor needs to know its hostname under which it is reachable by
+      zuul-web. Otherwise live console log streaming doesn't work. In most cases
+      This is automatically detected correctly. But when running in environments
+      where it cannot determine its hostname correctly this can be overridden
+      here.
+
 .. attr:: merger
 
    .. attr:: git_user_email
diff --git a/tests/fixtures/zuul-executor-hostname.conf b/tests/fixtures/zuul-executor-hostname.conf
new file mode 100644
index 0000000..7db144d
--- /dev/null
+++ b/tests/fixtures/zuul-executor-hostname.conf
@@ -0,0 +1,32 @@
+[gearman]
+server=127.0.0.1
+
+[statsd]
+# note, use 127.0.0.1 rather than localhost to avoid getting ipv6
+# see: https://github.com/jsocol/pystatsd/issues/61
+server=127.0.0.1
+
+[scheduler]
+tenant_config=main.yaml
+
+[merger]
+git_dir=/tmp/zuul-test/merger-git
+git_user_email=zuul@example.com
+git_user_name=zuul
+
+[executor]
+git_dir=/tmp/zuul-test/executor-git
+hostname=test-executor-hostname.openstack.org
+
+[connection gerrit]
+driver=gerrit
+server=review.example.com
+user=jenkins
+sshkey=fake_id_rsa_path
+
+[connection smtp]
+driver=smtp
+server=localhost
+port=25
+default_from=zuul@example.com
+default_to=you@example.com
diff --git a/tests/unit/test_executor.py b/tests/unit/test_executor.py
index 9c45645..ac7ae34 100755
--- a/tests/unit/test_executor.py
+++ b/tests/unit/test_executor.py
@@ -401,3 +401,12 @@
         node['ssh_port'] = 22022
         keys = self.test_job.getHostList({'nodes': [node]})[0]['host_keys']
         self.assertEqual(keys[0], '[localhost]:22022 fake-host-key')
+
+
+class TestExecutorHostname(ZuulTestCase):
+    config_file = 'zuul-executor-hostname.conf'
+    tenant_config_file = 'config/single-tenant/main.yaml'
+
+    def test_executor_hostname(self):
+        self.assertEqual('test-executor-hostname.openstack.org',
+                         self.executor_server.hostname)
diff --git a/zuul/executor/server.py b/zuul/executor/server.py
index 5998922..524386f 100644
--- a/zuul/executor/server.py
+++ b/zuul/executor/server.py
@@ -1535,7 +1535,8 @@
         self.jobdir_root = jobdir_root
         # TODOv3(mordred): make the executor name more unique --
         # perhaps hostname+pid.
-        self.hostname = socket.gethostname()
+        self.hostname = get_default(self.config, 'executor', 'hostname',
+                                    socket.gethostname())
         self.log_streaming_port = log_streaming_port
         self.merger_lock = threading.Lock()
         self.run_lock = threading.Lock()