aboutsummaryrefslogtreecommitdiffstats
path: root/network/scripts/run-os-net-config.sh
blob: 864da24b71a61ad728704e11fcc9ef84b6fb0f3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/bin/bash
# The following environment variables may be set to substitute in a
# custom bridge or interface name.  Normally these are provided by the calling
# SoftwareConfig resource, but they may also be set manually for testing.
# $bridge_name : The bridge device name to apply
# $interface_name : The interface name to apply
#
# Also this token is replaced via a str_replace in the SoftwareConfig running
# the script - in future we may extend this to also work with a variable, e.g
# a deployment input via input_values
# $network_config : the json serialized os-net-config config to apply
#
set -eux

function get_metadata_ip() {

  local METADATA_IP

  # Look for a variety of Heat transports
  # FIXME: Heat should provide a way to obtain this in a single place
  for URL in os-collect-config.cfn.metadata_url os-collect-config.heat.auth_url os-collect-config.request.metadata_url os-collect-config.zaqar.auth_url; do
    METADATA_IP=$(os-apply-config --key $URL --key-default '' --type raw 2>/dev/null | sed -e 's|http.*://\([^:]*\).*|\1|')
    [ -n "$METADATA_IP" ] && break
  done

  echo $METADATA_IP

}

function is_local_ip() {
  local IP_TO_CHECK=$1
  if ip -o a | grep "inet6\? $IP_TO_CHECK/" &>/dev/null; then
    return 0
  else
    return 1
  fi
}

function ping_metadata_ip() {
  local METADATA_IP=$(get_metadata_ip)

  if [ -n "$METADATA_IP" ] && ! is_local_ip $METADATA_IP; then

    echo -n "Trying to ping metadata IP ${METADATA_IP}..."

    local COUNT=0
    until ping -c 1 $METADATA_IP &> /dev/null; do
      COUNT=$(( $COUNT + 1 ))
      if [ $COUNT -eq 10 ]; then
        echo "FAILURE"
        echo "$METADATA_IP is not pingable." >&2
        exit 1
      fi
    done
    echo "SUCCESS"

  else
    echo "No metadata IP found. Skipping."
  fi
}

function configure_safe_defaults() {

[[ $? == 0 ]] && return 0

cat > /etc/os-net-config/dhcp_all_interfaces.yaml <<EOF_CAT
# This file is an autogenerated safe defaults file for os-net-config
# which runs DHCP on all discovered interfaces to ensure connectivity
# back to the undercloud for updates
network_config:
EOF_CAT

    for iface in $(ls /sys/class/net | grep -v ^lo$); do
        local mac_addr_type="$(cat /sys/class/net/${iface}/addr_assign_type)"
        if [ "$mac_addr_type" != "0" ]; then
            echo "Device has generated MAC, skipping."
        else
            ip link set dev $iface up &>/dev/null
            HAS_LINK="$(cat /sys/class/net/${iface}/carrier)"

            TRIES=10
            while [ "$HAS_LINK" == "0" -a $TRIES -gt 0 ]; do
                HAS_LINK="$(cat /sys/class/net/${iface}/carrier)"
                if [ "$HAS_LINK" == "1" ]; then
                    break
                else
                    sleep 1
                fi
                TRIES=$(( TRIES - 1 ))
            done
            if [ "$HAS_LINK" == "1" ] ; then
cat >> /etc/os-net-config/dhcp_all_interfaces.yaml <<EOF_CAT
  -
    type: interface
    name: $iface
    use_dhcp: true
EOF_CAT
            fi
        fi
    done
    set +e
    os-net-config -c /etc/os-net-config/dhcp_all_interfaces.yaml -v --detailed-exit-codes --cleanup
    RETVAL=$?
    set -e
    if [[ $RETVAL == 2 ]]; then
        ping_metadata_ip
    elif [[ $RETVAL != 0 ]]; then
        echo "ERROR: configuration of safe defaults failed."
    fi
}

if [ -n '$network_config' ]; then
    if [ -z "${disable_configure_safe_defaults:-}" ]; then
        trap configure_safe_defaults EXIT
    fi

    mkdir -p /etc/os-net-config
    # Note these variables come from the calling heat SoftwareConfig
    echo '$network_config' > /etc/os-net-config/config.json

    if [ "$(type -t network_config_hook)" = "function" ]; then
        network_config_hook
    fi

    sed -i "s/bridge_name/${bridge_name:-''}/" /etc/os-net-config/config.json
    sed -i "s/interface_name/${interface_name:-''}/" /etc/os-net-config/config.json

    set +e
    os-net-config -c /etc/os-net-config/config.json -v --detailed-exit-codes
    RETVAL=$?
    set -e

    if [[ $RETVAL == 2 ]]; then
        ping_metadata_ip

        #NOTE: dprince this udev rule can apparently leak DHCP processes?
        # https://bugs.launchpad.net/tripleo/+bug/1538259
        # until we discover the root cause we can simply disable the
        # rule because networking has already been configured at this point
        if [ -f /etc/udev/rules.d/99-dhcp-all-interfaces.rules ]; then
            rm /etc/udev/rules.d/99-dhcp-all-interfaces.rules
        fi

    elif [[ $RETVAL != 0 ]]; then
        echo "ERROR: os-net-config configuration failed." >&2
        exit 1
    fi
fi