<NME> setup.py
<BEF> from pathlib import Path

from setuptools import setup


def get_advanced_templates():
    template_base = 'aws/templates/advanced/'
    template_names = ['advanced-master', 'advanced-priv-agent', 'advanced-pub-agent', 'infra', 'zen']

    return [template_base + name + '.json' for name in template_names]


# These files are expected source files to the dcos-builder docker.
# They need to match the contents of ./pkgpanda/docker/dcos-builder/*
# exactly otherwise the dcos-builder docker will have a different sha1
# checksum calculated during when the ./release script is run.
# That leads to cached packages hashes being different from what
# is cached in S3 and prevents us from building DC/OS locally.
expected_dcos_builder_files = [
    Path('docker/dcos-builder/Dockerfile'),
    Path('docker/dcos-builder/README.md'),
]
dcos_builder_files = [f.relative_to(Path("./pkgpanda")) for f in Path("./pkgpanda").glob('docker/**/*') if f.is_file()]
if set(expected_dcos_builder_files) != set(dcos_builder_files):
    raise Exception('Expected ./pkgpanda/docker/dcos-builder to contain {} but it had {}'.format(
        expected_dcos_builder_files, dcos_builder_files))


setup(
    name='dcos_image',
    version='0.1',
    description='DC/OS cluster configuration, assembly, and maintenance code',
    url='https://dcos.io',
    author='Mesosphere, Inc.',
    author_email='help@dcos.io',
    license='apache2',
    classifiers=[
        'Development Status :: 3 - Alpha',
        'License :: OSI Approved :: Apache Software License',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.6',
    ],
    packages=[
        'dcos_installer',
        'gen',
        'gen.build_deploy',
        'pkgpanda',
        'pkgpanda.build',
        'pkgpanda.http',
        'release',
        'release.storage'],
    install_requires=[
        # DCOS-21656 - `botocore`` requires less than 2.7.0 while
        # `analytics-python` package installs 2.7.0 version
        'python-dateutil>=2.1,<2.7.0',
        'aiohttp==0.22.5',
        'analytics-python',
        'coloredlogs',
        'Flask',
        'flask-compress',
        'urllib3==1.25.10',
        'chardet<4.0',
        'PyJWT',
        # Pins taken from 'azure==2.0.0rc4'
        'msrest==0.4.17',
        'msrestazure==0.4.15',
        'azure-common==1.1.4',
        'azure-storage==0.32.0',
        'azure-mgmt-network==0.30.0rc4',
        'azure-mgmt-resource==0.30.0rc4',
        'botocore',
        'boto3',
    package_data={
        'gen': [
            'ip-detect/aws.sh',
            'ip-detect/aws_public.sh',
            'ip-detect/azure.sh',
            'ip-detect/vagrant.sh',
            'fault-domain-detect/cloud.sh',
            'cloud-config.yaml',
            'dcos-config.yaml',
            'dcos-metadata.yaml',
        'console_scripts': [
            'release=release:main',
            'pkgpanda=pkgpanda.cli:main',
            'mkpanda=pkgpanda.build.cli:main',
            'dcos_installer=dcos_installer.cli:main',
        ],
    },
    package_data={
        'gen': [
            'ip-detect/aws.sh',
            'ip-detect/aws6.sh',
            'ip-detect/aws_public.sh',
            'ip-detect/azure.ps1',
            'ip-detect/azure.sh',
            'ip-detect/azure6.sh',
            'ip-detect/vagrant.sh',
            'ip-detect/vagrant6.sh',
            'fault-domain-detect/cloud.sh',
            'fault-domain-detect/aws.sh',
            'fault-domain-detect/azure.sh',
            'cloud-config.yaml',
            'cloud-config-windows.yaml',
            'dcos-config.yaml',
            'dcos-config-win.yaml',
            'dcos-config-windows.yaml',
            'dcos-metadata.yaml',
            'dcos-services.yaml',
            'dcos-services-windows.yaml',
            'aws/dcos-config.yaml',
            'aws/templates/aws.html',
            'aws/templates/cloudformation.json',
            'azure/cloud-config.yaml',
            'azure/cloud-config-windows.yaml',
            'azure/azuredeploy-parameters.json',
            'azure/templates/acs.json',
            'azure/templates/azure.html',
            'azure/templates/azuredeploy.json',
            'build_deploy/bash/dcos_generate_config.sh.in',
            'build_deploy/bash/Dockerfile.in',
            'build_deploy/bash/installer_internal_wrapper.in',
            'build_deploy/bash/dcos-launch.spec',
            'build_deploy/powershell/dcos_install.ps1.in',
            'build_deploy/powershell/dcos_node_upgrade.ps1.in',
            'coreos-aws/cloud-config.yaml',
            'coreos/cloud-config.yaml'
        ] + get_advanced_templates(),
        'pkgpanda': [str(f) for f in expected_dcos_builder_files],
    },
    zip_safe=False
)

<MSG> Merge #2219

<DFF> @@ -73,10 +73,15 @@ setup(
     package_data={
         'gen': [
             'ip-detect/aws.sh',
+            'ip-detect/aws6.sh',
             'ip-detect/aws_public.sh',
             'ip-detect/azure.sh',
+            'ip-detect/azure6.sh',
             'ip-detect/vagrant.sh',
+            'ip-detect/vagrant6.sh',
             'fault-domain-detect/cloud.sh',
+            'fault-domain-detect/aws.sh',
+            'fault-domain-detect/azure.sh',
             'cloud-config.yaml',
             'dcos-config.yaml',
             'dcos-metadata.yaml',

{'commit': 'diff --git a/gen/build_deploy/aws.py b/gen/build_deploy/aws.py\nindex 196bb2ab..3a99c355 100644\n--- a/gen/build_deploy/aws.py\n+++ b/gen/build_deploy/aws.py\n@@ -49,6 +49,7 @@ aws_base_source = Source(entry={\n         \'aws_stack_name\': Late(\'{ "Ref" : "AWS::StackName" }\'),\n         \'ip_detect_contents\': get_ip_detect(\'aws\'),\n         \'ip_detect_public_contents\': calculate_ip_detect_public_contents,\n+        \'ip6_detect_contents\': get_ip_detect(\'aws6\'),\n         \'exhibitor_explicit_keys\': \'false\',\n         \'cluster_name\': Late(\'{ "Ref" : "AWS::StackName" }\'),\n         \'master_discovery\': \'master_http_loadbalancer\',\ndiff --git a/gen/build_deploy/azure.py b/gen/build_deploy/azure.py\nindex e9e7cef5..b14768be 100644\n--- a/gen/build_deploy/azure.py\n+++ b/gen/build_deploy/azure.py\n@@ -54,6 +54,7 @@ azure_base_source = Source(entry={\n     \'must\': {\n         \'resolvers\': \'["168.63.129.16"]\',\n         \'ip_detect_contents\': yaml.dump(pkg_resources.resource_string(\'gen\', \'ip-detect/azure.sh\').decode()),\n+        \'ip6_detect_contents\': yaml.dump(pkg_resources.resource_string(\'gen\', \'ip-detect/azure6.sh\').decode()),\n         \'master_discovery\': \'static\',\n         \'exhibitor_storage_backend\': \'azure\',\n         \'master_cloud_config\': \'{{ master_cloud_config }}\',\ndiff --git a/gen/build_deploy/bash.py b/gen/build_deploy/bash.py\nindex 2035a2d2..60f0d83a 100644\n--- a/gen/build_deploy/bash.py\n+++ b/gen/build_deploy/bash.py\n@@ -79,6 +79,7 @@ onprem_source = Source(entry={\n         \'platform\': \'onprem\',\n         \'resolvers\': \'["8.8.8.8", "8.8.4.4"]\',\n         \'ip_detect_filename\': \'genconf/ip-detect\',\n+        \'ip6_detect_filename\': \'\',\n         \'bootstrap_id\': lambda: calculate_environment_variable(\'BOOTSTRAP_ID\'),\n         \'enable_docker_gc\': \'false\'\n     },\ndiff --git a/gen/calc.py b/gen/calc.py\nindex b823831e..d3e0bc79 100644\n--- a/gen/calc.py\n+++ b/gen/calc.py\n@@ -229,6 +229,12 @@ def calculate_ip_detect_public_contents(ip_detect_contents, ip_detect_public_fil\n     return ip_detect_contents\n \n \n+def calculate_ip6_detect_contents(ip6_detect_filename):\n+    if ip6_detect_filename != \'\':\n+        return yaml.dump(open(ip6_detect_filename, encoding=\'utf-8\').read())\n+    return yaml.dump("")\n+\n+\n def calculate_rexray_config_contents(rexray_config):\n     return yaml.dump(\n         # Assume block style YAML (not flow) for REX-Ray config.\n@@ -969,6 +975,7 @@ entry = {\n         lambda mesos_master_work_dir: validate_absolute_path(mesos_master_work_dir),\n         lambda mesos_agent_work_dir: validate_absolute_path(mesos_agent_work_dir),\n         lambda licensing_enabled: validate_true_false(licensing_enabled),\n+        lambda enable_mesos_ipv6_discovery: validate_true_false(enable_mesos_ipv6_discovery),\n     ],\n     \'default\': {\n         \'bootstrap_tmp_dir\': \'tmp\',\n@@ -993,6 +1000,7 @@ entry = {\n         \'ip_detect_contents\': calculate_ip_detect_contents,\n         \'ip_detect_public_filename\': \'\',\n         \'ip_detect_public_contents\': calculate_ip_detect_public_contents,\n+        \'ip6_detect_contents\': calculate_ip6_detect_contents,\n         \'dns_search\': \'\',\n         \'auth_cookie_secure_flag\': \'false\',\n         \'master_dns_bindall\': \'true\',\n@@ -1073,6 +1081,7 @@ entry = {\n         \'fault_domain_detect_filename\': \'genconf/fault-domain-detect\',\n         \'fault_domain_detect_contents\': calculate_fault_domain_detect_contents,\n         \'license_key_contents\': \'\',\n+        \'enable_mesos_ipv6_discovery\': \'false\'\n     },\n     \'must\': {\n         \'fault_domain_enabled\': \'false\',\ndiff --git a/gen/dcos-config.yaml b/gen/dcos-config.yaml\nindex f6f648a5..319cc496 100644\n--- a/gen/dcos-config.yaml\n+++ b/gen/dcos-config.yaml\n@@ -18,6 +18,9 @@ package:\n   - path: /bin/detect_ip_public\n     permissions: "0755"\n     content: {{ ip_detect_public_contents }}\n+  - path: /bin/detect_ip6\n+    permissions: "0755"\n+    content: {{ ip6_detect_contents }}\n   - path: /etc/check_time.env\n     content: |\n         ENABLE_CHECK_TIME={{ check_time }}\n@@ -505,6 +508,11 @@ package:\n       MESOS_DOCKER_CONFIG=file://{{ cluster_docker_credentials_path }}\n {% case "false" %}\n {% endswitch %}\n+{% switch enable_mesos_ipv6_discovery %}\n+{% case "false" %}\n+{% case "true" %}\n+      MESOS_IP6_DISCOVERY_COMMAND=/opt/mesosphere/bin/detect_ip6\n+{% endswitch %}\n {% switch cluster_docker_credentials_dcos_owned %}\n {% case "true" %}\n   - path: /etc/docker_credentials\ndiff --git a/gen/ip-detect/aws6.sh b/gen/ip-detect/aws6.sh\nnew file mode 100755\nindex 00000000..0eb5645e\n--- /dev/null\n+++ b/gen/ip-detect/aws6.sh\n@@ -0,0 +1,19 @@\n+#!/bin/sh\n+set -o nounset -o errexit\n+\n+# Get COREOS COREOS_PRIVATE_IPV6\n+if [ -e /etc/environment ]\n+then\n+  set -o allexport\n+  source /etc/environment\n+  set +o allexport\n+fi\n+\n+# Get the IP address of the interface specified by $1\n+get_private_ip_from_metaserver()\n+{\n+    MAC=$(ip addr show dev $1 | awk \'/ether/ {print $2}\')\n+    curl -fsSL http://169.254.169.254/latest/meta-data/network/interfaces/macs/$MAC/ipv6s\n+}\n+\n+echo ${COREOS_PRIVATE_IPV6:-$(get_private_ip_from_metaserver eth0)}\ndiff --git a/gen/ip-detect/azure6.sh b/gen/ip-detect/azure6.sh\nnew file mode 100755\nindex 00000000..5c87ccf5\n--- /dev/null\n+++ b/gen/ip-detect/azure6.sh\n@@ -0,0 +1,18 @@\n+#!/bin/sh\n+set -o nounset -o errexit\n+\n+# Get COREOS COREOS_PRIVATE_IPV6\n+if [ -e /etc/environment ]\n+then\n+  set -o allexport\n+  . /etc/environment\n+  set +o allexport\n+fi\n+\n+# Get the IP address of the interface specified by $1\n+get_ip_from_interface()\n+{\n+  ip -6 addr show $1 | grep "scope global" | awk -F \'[ \\t]+|/\' \'{print $3}\'\n+}\n+\n+echo ${COREOS_PRIVATE_IPV6:-$(get_ip_from_interface eth0)}\ndiff --git a/gen/ip-detect/vagrant6.sh b/gen/ip-detect/vagrant6.sh\nnew file mode 100755\nindex 00000000..d0fe7323\n--- /dev/null\n+++ b/gen/ip-detect/vagrant6.sh\n@@ -0,0 +1,19 @@\n+#!/usr/bin/env bash\n+set -o nounset -o errexit\n+\n+# Get COREOS COREOS_PRIVATE_IPV6\n+if [ -e /etc/environment ]\n+then\n+  set -o allexport\n+  source /etc/environment\n+  set +o allexport\n+fi\n+\n+\n+get_defaultish_ip()\n+{\n+    ipv6=$(ip -6 route get 2001:4860:4860::8888 | awk \'{print $9; exit}\')\n+    echo $ipv6\n+}\n+\n+echo ${COREOS_PRIVATE_IPV6:-$(get_defaultish_ip)}\ndiff --git a/gen/tests/test_validate.py b/gen/tests/test_validate.py\nindex 41480361..f6935af3 100644\n--- a/gen/tests/test_validate.py\n+++ b/gen/tests/test_validate.py\n@@ -36,6 +36,7 @@ def test_error_during_validate(monkeypatch):\n         \'bootstrap_url\': \'\',\n         \'bootstrap_variant\': \'\',\n         \'ip_detect_contents\': \'\',  # so that ip_detect_filename doesn\'t get used from onprem_source\n+        \'ip6_detect_contents\': \'\',\n         \'exhibitor_storage_backend\': \'static\',\n         \'master_discovery\': \'static\',\n         \'cluster_name\': \'foobar\',\ndiff --git a/gen/tests/utils.py b/gen/tests/utils.py\nindex 461d1879..e7616b7a 100644\n--- a/gen/tests/utils.py\n+++ b/gen/tests/utils.py\n@@ -19,6 +19,7 @@ def make_arguments(new_arguments):\n     """\n     arguments = copy.deepcopy({\n         \'ip_detect_filename\': pkg_resources.resource_filename(\'gen\', \'ip-detect/aws.sh\'),\n+        \'ip6_detect_filename\': pkg_resources.resource_filename(\'gen\', \'ip-detect/aws6.sh\'),\n         \'bootstrap_id\': \'123\',\n         \'package_ids\': json.dumps([\'package--version\']),\n         \'exhibitor_zk_path\': \'/dcos\',\ndiff --git a/setup.py b/setup.py\nindex 7cba1460..e5244470 100644\n--- a/setup.py\n+++ b/setup.py\n@@ -73,10 +73,15 @@ setup(\n     package_data={\n         \'gen\': [\n             \'ip-detect/aws.sh\',\n+            \'ip-detect/aws6.sh\',\n             \'ip-detect/aws_public.sh\',\n             \'ip-detect/azure.sh\',\n+            \'ip-detect/azure6.sh\',\n             \'ip-detect/vagrant.sh\',\n+            \'ip-detect/vagrant6.sh\',\n             \'fault-domain-detect/cloud.sh\',\n+            \'fault-domain-detect/aws.sh\',\n+            \'fault-domain-detect/azure.sh\',\n             \'cloud-config.yaml\',\n             \'dcos-config.yaml\',\n             \'dcos-metadata.yaml\',\n', 'commit_subject': 'Merge #2219', 'repo_name': 'dcos/dcos', 'committer': {'name': 'mergebot', 'email': 'f97a3749d7f7a6acffeb32254927c8ceca7059ca@mesosphere.io', 'time_sec': '1519855375', 'tz_offset': '0', 'date': {'seconds': '1519855375'}}, 'commit_tree': 'adcb3a18abbdf3d65adf3dd4894f3f617bcb1f4a', 'commit_message': 'Merge #2219\n', 'language_name': 'Go', 'license': 'apache-2.0', 'hunks': "@@ -73,10 +73,15 @@ setup(\n     package_data={\n         'gen': [\n             'ip-detect/aws.sh',\n+            'ip-detect/aws6.sh',\n             'ip-detect/aws_public.sh',\n             'ip-detect/azure.sh',\n+            'ip-detect/azure6.sh',\n             'ip-detect/vagrant.sh',\n+            'ip-detect/vagrant6.sh',\n             'fault-domain-detect/cloud.sh',\n+            'fault-domain-detect/aws.sh',\n+            'fault-domain-detect/azure.sh',\n             'cloud-config.yaml',\n             'dcos-config.yaml',\n             'dcos-metadata.yaml',\n", 'addition_count': 5, 'deletion_count': 0, 'src_file': 'a/setup.py', 'tgt_file': 'b/setup.py', 'file_extension': '.py', 'before_file': 'from pathlib import Path\n\nfrom setuptools import setup\n\n\ndef get_advanced_templates():\n    template_base = \'aws/templates/advanced/\'\n    template_names = [\'advanced-master\', \'advanced-priv-agent\', \'advanced-pub-agent\', \'infra\', \'zen\']\n\n    return [template_base + name + \'.json\' for name in template_names]\n\n\n# These files are expected source files to the dcos-builder docker.\n# They need to match the contents of ./pkgpanda/docker/dcos-builder/*\n# exactly otherwise the dcos-builder docker will have a different sha1\n# checksum calculated during when the ./release script is run.\n# That leads to cached packages hashes being different from what\n# is cached in S3 and prevents us from building DC/OS locally.\nexpected_dcos_builder_files = [\n    Path(\'docker/dcos-builder/Dockerfile\'),\n    Path(\'docker/dcos-builder/README.md\'),\n]\ndcos_builder_files = [f.relative_to(Path("./pkgpanda")) for f in Path("./pkgpanda").glob(\'docker/**/*\') if f.is_file()]\nif set(expected_dcos_builder_files) != set(dcos_builder_files):\n    raise Exception(\'Expected ./pkgpanda/docker/dcos-builder to contain {} but it had {}\'.format(\n        expected_dcos_builder_files, dcos_builder_files))\n\n\nsetup(\n    name=\'dcos_image\',\n    version=\'0.1\',\n    description=\'DC/OS cluster configuration, assembly, and maintenance code\',\n    url=\'https://dcos.io\',\n    author=\'Mesosphere, Inc.\',\n    author_email=\'help@dcos.io\',\n    license=\'apache2\',\n    classifiers=[\n        \'Development Status :: 3 - Alpha\',\n        \'License :: OSI Approved :: Apache Software License\',\n        \'Programming Language :: Python :: 3\',\n        \'Programming Language :: Python :: 3.6\',\n    ],\n    packages=[\n        \'dcos_installer\',\n        \'gen\',\n        \'gen.build_deploy\',\n        \'pkgpanda\',\n        \'pkgpanda.build\',\n        \'pkgpanda.http\',\n        \'release\',\n        \'release.storage\'],\n    install_requires=[\n        # DCOS-21656 - `botocore`` requires less than 2.7.0 while\n        # `analytics-python` package installs 2.7.0 version\n        \'python-dateutil>=2.1,<2.7.0\',\n        \'aiohttp==0.22.5\',\n        \'analytics-python\',\n        \'coloredlogs\',\n        \'Flask\',\n        \'flask-compress\',\n        \'urllib3==1.25.10\',\n        \'chardet<4.0\',\n        \'PyJWT\',\n        # Pins taken from \'azure==2.0.0rc4\'\n        \'msrest==0.4.17\',\n        \'msrestazure==0.4.15\',\n        \'azure-common==1.1.4\',\n        \'azure-storage==0.32.0\',\n        \'azure-mgmt-network==0.30.0rc4\',\n        \'azure-mgmt-resource==0.30.0rc4\',\n        \'botocore\',\n        \'boto3\',\n    package_data={\n        \'gen\': [\n            \'ip-detect/aws.sh\',\n            \'ip-detect/aws_public.sh\',\n            \'ip-detect/azure.sh\',\n            \'ip-detect/vagrant.sh\',\n            \'fault-domain-detect/cloud.sh\',\n            \'cloud-config.yaml\',\n            \'dcos-config.yaml\',\n            \'dcos-metadata.yaml\',\n        \'console_scripts\': [\n            \'release=release:main\',\n            \'pkgpanda=pkgpanda.cli:main\',\n            \'mkpanda=pkgpanda.build.cli:main\',\n            \'dcos_installer=dcos_installer.cli:main\',\n        ],\n    },\n    package_data={\n        \'gen\': [\n            \'ip-detect/aws.sh\',\n            \'ip-detect/aws6.sh\',\n            \'ip-detect/aws_public.sh\',\n            \'ip-detect/azure.ps1\',\n            \'ip-detect/azure.sh\',\n            \'ip-detect/azure6.sh\',\n            \'ip-detect/vagrant.sh\',\n            \'ip-detect/vagrant6.sh\',\n            \'fault-domain-detect/cloud.sh\',\n            \'fault-domain-detect/aws.sh\',\n            \'fault-domain-detect/azure.sh\',\n            \'cloud-config.yaml\',\n            \'cloud-config-windows.yaml\',\n            \'dcos-config.yaml\',\n            \'dcos-config-win.yaml\',\n            \'dcos-config-windows.yaml\',\n            \'dcos-metadata.yaml\',\n            \'dcos-services.yaml\',\n            \'dcos-services-windows.yaml\',\n            \'aws/dcos-config.yaml\',\n            \'aws/templates/aws.html\',\n            \'aws/templates/cloudformation.json\',\n            \'azure/cloud-config.yaml\',\n            \'azure/cloud-config-windows.yaml\',\n            \'azure/azuredeploy-parameters.json\',\n            \'azure/templates/acs.json\',\n            \'azure/templates/azure.html\',\n            \'azure/templates/azuredeploy.json\',\n            \'build_deploy/bash/dcos_generate_config.sh.in\',\n            \'build_deploy/bash/Dockerfile.in\',\n            \'build_deploy/bash/installer_internal_wrapper.in\',\n            \'build_deploy/bash/dcos-launch.spec\',\n            \'build_deploy/powershell/dcos_install.ps1.in\',\n            \'build_deploy/powershell/dcos_node_upgrade.ps1.in\',\n            \'coreos-aws/cloud-config.yaml\',\n            \'coreos/cloud-config.yaml\'\n        ] + get_advanced_templates(),\n        \'pkgpanda\': [str(f) for f in expected_dcos_builder_files],\n    },\n    zip_safe=False\n)\n', 'message': 'Merge #2219\n', 'author_name': 'mergebot', 'lang': 'py'}