Skip to content

Commit

Permalink
Implement a workaround for the IPv6 issue
Browse files Browse the repository at this point in the history
We observed intermittent failures during deployment, due to Go resolving Google API domains into IPv6 addresses, even though the Cloud Shell environment has IPv6 disabled.

Until the Go issue (golang/go#25321) has been resolved, we have to patch the `/etc/hosts` file on the Cloud Shell machine to ensure that these domains are resolved using IPv4 only.

PiperOrigin-RevId: 495598377
  • Loading branch information
dulacp authored and copybara-github committed Dec 15, 2022
1 parent 0e6aa28 commit ca680b1
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
*.swp
__pycache__
*.pyc
crmint.egg-info/

# System Files
.DS_Store
Expand Down
2 changes: 2 additions & 0 deletions cli/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
*.egg-info
stages/*.py
build/
dist/
16 changes: 16 additions & 0 deletions cli/commands/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,20 @@ def terraform_switch_workspace(stage: shared.StageContext,
debug=debug)


def patch_etc_hosts(debug: bool = False) -> None:
"""Workaround to avoid Terraform to use IPv6 addresses."""
cmd = 'bash scripts/force_ipv4_addresses.sh'
shared.execute_command(
'Patch /etc/hosts to force IPv4', cmd, cwd='./cli', debug=debug)


def unpatch_etc_hosts(debug: bool = False) -> None:
"""Restores the `/etc/hosts` file."""
cmd = 'sudo cp /etc/hosts.backup /etc/hosts'
shared.execute_command(
'Restore /etc/hosts', cmd, cwd='./cli', debug=debug)


def terraform_init(debug: bool = False) -> bool:
"""Runs the Terraform init command."""
cmd = 'terraform init -upgrade'
Expand Down Expand Up @@ -352,6 +366,7 @@ def setup(stage_path: Union[None, str], debug: bool) -> None:
sys.exit(1)

# Switches workspace.
patch_etc_hosts(debug=debug)
terraform_init(debug=debug)
terraform_switch_workspace(stage, debug=debug)

Expand All @@ -363,6 +378,7 @@ def setup(stage_path: Union[None, str], debug: bool) -> None:
terraform_plan(stage, debug=debug)
configuration_summary_from_plan(debug=debug)
terraform_apply(debug=debug)
unpatch_etc_hosts(debug=debug)
click.echo(click.style('Done.', fg='magenta', bold=True))


Expand Down
2 changes: 2 additions & 0 deletions cli/commands/cloud_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ def test_validates_stdout_without_vpc(self):
textwrap.dedent("""\
>>>> Setup
Project ID found: dummy_project_with_vpc
---> Patch /etc/hosts to force IPv4 ✓
---> Initialize Terraform ✓
---> List Terraform workspaces ✓
---> Create new Terraform workspace: dummy_project_with_vpc ✓
Expand All @@ -215,6 +216,7 @@ def test_validates_stdout_without_vpc(self):
Cloud Run Service IAM Member \\(3\\)
(.|\\n)*
---> Apply Terraform plan \\(~10min\\) ✓
---> Restore /etc/hosts ✓
Done.
""")
)
Expand Down
59 changes: 59 additions & 0 deletions cli/scripts/force_ipv4_addresses.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/bash
#
# IPv6 is disabled in Google Cloud Shell, though the DNS resolution in Go
# does not always comply with this setting and from time to time resolves to
# an IPv6 address.
#
# The following workaround as been described proposes, waiting for the Go team
# to solve this properly (https://github.com/golang/go/issues/25321).
#
# See: https://github.com/hashicorp/terraform-provider-google/issues/6782
#

# Checks that we run inside a Google VM.
GMETADATA_ADDR=`dig +short metadata.google.internal`
if [[ "${GMETADATA_ADDR}" == "" ]]; then
echo "Not on a Google VM, no need to patch the /etc/hosts file."
exit 0
fi

# Backup existing /etc/hosts.
if [ ! -f /etc/hosts.backup ]; then
sudo cp /etc/hosts /etc/hosts.backup
fi

read -r -d '' APIS << EOM
aiplatform.googleapis.com
analytics.googleapis.com
analyticsadmin.googleapis.com
analyticsreporting.googleapis.com
cloudbuild.googleapis.com
cloudresourcemanager.googleapis.com
cloudscheduler.googleapis.com
compute.googleapis.com
container.googleapis.com
googleapis.com
iam.googleapis.com
logging.googleapis.com
monitoring.googleapis.com
pubsub.googleapis.com
secretmanager.googleapis.com
servicenetworking.googleapis.com
sqladmin.googleapis.com
storage-api.googleapis.com
storage-component.googleapis.com
storage.googleapis.com
www.googleapis.com
EOM

# Restores the backup content.
sudo sh -c "cat /etc/hosts.backup > /etc/hosts"

# Adds IPv4 addresses for each Google Cloud API.
sudo sh -c "echo -e '\n# Forcing IPv4 to workaround a Go issue: https://github.com/golang/go/issues/25321' >> /etc/hosts"
for name in $APIS
do
ipv4=$(getent ahostsv4 "$name" | head -n 1 | awk '{ print $1 }')
sudo sh -c "echo '$ipv4 $name' >> /etc/hosts"
echo "Forced IPv4 for $name: $ipv4"
done

0 comments on commit ca680b1

Please sign in to comment.