github.com/coreos/mantle@v0.13.0/kola/tests/etcd/discovery.go (about) 1 // Copyright 2015 CoreOS, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package etcd 16 17 import ( 18 "encoding/json" 19 20 "github.com/coreos/pkg/capnslog" 21 22 "github.com/coreos/mantle/kola/cluster" 23 "github.com/coreos/mantle/kola/register" 24 "github.com/coreos/mantle/platform/conf" 25 ) 26 27 var plog = capnslog.NewPackageLogger("github.com/coreos/mantle", "kola/tests/etcd") 28 29 func init() { 30 register.Register(®ister.Test{ 31 Run: Discovery, 32 ClusterSize: 3, 33 Name: "cl.etcd-member.discovery", 34 UserData: conf.ContainerLinuxConfig(`etcd: 35 listen_client_urls: http://0.0.0.0:2379 36 advertise_client_urls: http://{PRIVATE_IPV4}:2379 37 listen_peer_urls: http://{PRIVATE_IPV4}:2380 38 initial_advertise_peer_urls: http://{PRIVATE_IPV4}:2380 39 discovery: $discovery`), 40 Flags: []register.Flag{register.RequiresInternetAccess}, // etcd-member requires networking 41 Distros: []string{"cl"}, 42 }) 43 44 register.Register(®ister.Test{ 45 Run: etcdMemberV2BackupRestore, 46 ClusterSize: 1, 47 Name: "cl.etcd-member.v2-backup-restore", 48 UserData: conf.ContainerLinuxConfig(` 49 50 etcd: 51 listen_client_urls: http://0.0.0.0:4001,http://{PRIVATE_IPV4}:2379 52 advertise_client_urls: http://{PRIVATE_IPV4}:2379 53 listen_peer_urls: http://0.0.0.0:2380 54 initial_advertise_peer_urls: http://{PRIVATE_IPV4}:2380 55 discovery: $discovery 56 `), 57 Flags: []register.Flag{register.RequiresInternetAccess}, // etcd-member requires networking 58 ExcludePlatforms: []string{"esx"}, // etcd-member requires ct rendering 59 Distros: []string{"cl"}, 60 }) 61 62 register.Register(®ister.Test{ 63 Run: etcdmemberEtcdctlV3, 64 // Clustersize of 1 to avoid needing private ips everywhere for clustering; 65 // this lets it run on more platforms, and also faster 66 ClusterSize: 1, 67 Name: "cl.etcd-member.etcdctlv3", 68 UserData: conf.ContainerLinuxConfig(` 69 70 etcd: 71 listen_client_urls: http://0.0.0.0:2379 72 advertise_client_urls: http://127.0.0.1:2379 73 listen_peer_urls: http://0.0.0.0:2380 74 initial_advertise_peer_urls: http://127.0.0.1:2380 75 `), 76 Flags: []register.Flag{register.RequiresInternetAccess}, // networking to download etcd image 77 Distros: []string{"cl"}, 78 }) 79 } 80 81 func Discovery(c cluster.TestCluster) { 82 var err error 83 84 // NOTE(pb): this check makes the next code somewhat redundant 85 if err = GetClusterHealth(c, c.Machines()[0], len(c.Machines())); err != nil { 86 c.Fatalf("discovery failed cluster-health check: %v", err) 87 } 88 89 var keyMap map[string]string 90 keyMap, err = setKeys(c, 5) 91 if err != nil { 92 c.Fatalf("failed to set keys: %v", err) 93 } 94 95 if err = checkKeys(c, keyMap); err != nil { 96 c.Fatalf("failed to check keys: %v", err) 97 } 98 99 } 100 101 // etcdMemberV2BackupRestore tests that the basic etcdctl v2 operations (get, 102 // put, rm) work. It verifies that a backup and restore, similar to the one 103 // documented in 104 // https://coreos.com/etcd/docs/latest/v2/admin_guide.html#disaster-recovery 105 // works. 106 // Note, this is a v2 backup/restore being performed against the current v3 107 // etcd 108 func etcdMemberV2BackupRestore(c cluster.TestCluster) { 109 m := c.Machines()[0] 110 111 if err := GetClusterHealth(c, c.Machines()[0], len(c.Machines())); err != nil { 112 c.Fatalf("failed cluster-health check: %v", err) 113 } 114 115 c.MustSSH(m, ` 116 set -e 117 118 prefix=$RANDOM 119 etcdctl set /$prefix/test magic 120 res="$(etcdctl get /$prefix/test)" 121 if [[ "$res" != "magic" ]]; then 122 echo "Expected magic, got $res" 123 exit 1 124 fi 125 126 backup_to="$(mktemp -d)" 127 128 sudo etcdctl backup --data-dir=/var/lib/etcd \ 129 --backup-dir "${backup_to}" 130 131 etcdctl rm /$prefix/test 132 133 if etcdctl get /$prefix/test 2>&1; then 134 echo "Expected rm'd key to error on get, didn't" 135 exit 1 136 fi 137 138 sudo systemctl stop etcd-member 139 140 # Note: this means we're now a new cluster of size 1 because of how etcd2 141 # backup/restore works. 142 sudo rm -rf /var/lib/etcd 143 sudo mv "${backup_to}" /var/lib/etcd/ 144 sudo chown -R etcd:etcd /var/lib/etcd 145 146 sudo mkdir -p /run/systemd/system/etcd-member.service.d/ 147 sudo tee /run/systemd/system/etcd-member.service.d/10-force-new.conf <<EOF 148 [Service] 149 Environment=ETCD_FORCE_NEW_CLUSTER=true 150 EOF 151 152 sudo systemctl daemon-reload 153 sudo systemctl start etcd-member 154 155 res="$(etcdctl get /$prefix/test)" 156 if [[ "$res" != "magic" ]]; then 157 echo "Expected magic after backup-restore, got $res" 158 exit 1 159 fi 160 `) 161 } 162 163 // etcdmemberEtcdctlV3 tests the basic operation of the ETCDCTL_API=3 behavior 164 // of the etcdctl we ship. 165 func etcdmemberEtcdctlV3(c cluster.TestCluster) { 166 m := c.Machines()[0] 167 168 type etcdMemberOutput struct { 169 Members []struct { 170 ID uint64 171 Name string 172 PeerURLs []string 173 ClientURLs []string 174 } 175 } 176 memberJson := c.MustSSH(m, `ETCDCTL_API=3 etcdctl member list --write-out=json`) 177 178 members := etcdMemberOutput{} 179 if err := json.Unmarshal(memberJson, &members); err != nil { 180 c.Fatalf("could not unmarshal %s: %s", memberJson, err) 181 } 182 183 if len(members.Members) != len(c.Machines()) { 184 c.Fatalf("expected %v members; only got %v", len(c.Machines()), len(members.Members)) 185 } 186 187 c.MustSSH(m, ` 188 set -e 189 export ETCDCTL_API=3 190 if [[ "$(etcdctl put foo bar)" != "OK" ]]; then 191 echo "Put failed" 192 exit 1 193 fi 194 195 value="$(etcdctl get foo -w json | jq '.kvs[].value' -r | base64 -d)" 196 197 if [[ "${value}" != "bar" ]]; then 198 echo "Reading our put failed: expected bar, got ${value}" 199 exit 1 200 fi 201 202 backup_to="$(mktemp -d)" 203 204 sudo -E etcdctl snapshot save "${backup_to}/snapshot.db" 205 sudo -E etcdctl snapshot status "${backup_to}/snapshot.db" 206 `) 207 }