github.com/coreos/mantle@v0.13.0/kola/tests/ignition/resource.go (about) 1 // Copyright 2017 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 ignition 16 17 import ( 18 "bytes" 19 "fmt" 20 "io" 21 "net/http" 22 23 "github.com/coreos/go-semver/semver" 24 "github.com/pin/tftp" 25 26 "github.com/coreos/mantle/kola/cluster" 27 "github.com/coreos/mantle/kola/register" 28 "github.com/coreos/mantle/platform" 29 "github.com/coreos/mantle/platform/conf" 30 "github.com/coreos/mantle/platform/machine/packet" 31 ) 32 33 var ( 34 localClient = conf.Ignition(`{ 35 "ignition": { 36 "version": "2.1.0" 37 }, 38 "storage": { 39 "files": [ 40 { 41 "filesystem": "root", 42 "path": "/var/resource/data", 43 "contents": { 44 "source": "data:,kola-data" 45 }, 46 "mode": 420 47 }, 48 { 49 "filesystem": "root", 50 "path": "/var/resource/http", 51 "contents": { 52 "source": "http://$IP/http" 53 }, 54 "mode": 420 55 }, 56 { 57 "filesystem": "root", 58 "path": "/var/resource/tftp", 59 "contents": { 60 "source": "tftp://$IP/tftp" 61 }, 62 "mode": 420 63 } 64 ] 65 } 66 }`) 67 localClientV3 = conf.Ignition(`{ 68 "ignition": { 69 "version": "3.0.0" 70 }, 71 "storage": { 72 "files": [ 73 { 74 "path": "/var/resource/data", 75 "contents": { 76 "source": "data:,kola-data" 77 }, 78 "mode": 420 79 }, 80 { 81 "path": "/var/resource/http", 82 "contents": { 83 "source": "http://$IP/http" 84 }, 85 "mode": 420 86 }, 87 { 88 "path": "/var/resource/tftp", 89 "contents": { 90 "source": "tftp://$IP/tftp" 91 }, 92 "mode": 420 93 } 94 ] 95 } 96 }`) 97 ) 98 99 func init() { 100 register.Register(®ister.Test{ 101 Name: "coreos.ignition.resource.local", 102 Run: resourceLocal, 103 ClusterSize: 1, 104 NativeFuncs: map[string]func() error{ 105 "Serve": Serve, 106 }, 107 // https://github.com/coreos/bugs/issues/2205 108 ExcludePlatforms: []string{"do", "qemu-unpriv"}, 109 Distros: []string{"cl", "fcos", "rhcos"}, 110 }) 111 register.Register(®ister.Test{ 112 Name: "coreos.ignition.resource.remote", 113 Run: resourceRemote, 114 ClusterSize: 1, 115 Flags: []register.Flag{register.RequiresInternetAccess}, 116 // https://github.com/coreos/bugs/issues/2205 for DO 117 ExcludePlatforms: []string{"do"}, 118 UserData: conf.Ignition(`{ 119 "ignition": { 120 "version": "2.1.0" 121 }, 122 "storage": { 123 "files": [ 124 { 125 "filesystem": "root", 126 "path": "/var/resource/http", 127 "contents": { 128 "source": "http://s3-us-west-2.amazonaws.com/kola-fixtures/resources/anonymous" 129 }, 130 "mode": 420 131 }, 132 { 133 "filesystem": "root", 134 "path": "/var/resource/https", 135 "contents": { 136 "source": "https://s3-us-west-2.amazonaws.com/kola-fixtures/resources/anonymous" 137 }, 138 "mode": 420 139 }, 140 { 141 "filesystem": "root", 142 "path": "/var/resource/s3-anon", 143 "contents": { 144 "source": "s3://kola-fixtures/resources/anonymous" 145 }, 146 "mode": 420 147 } 148 ] 149 } 150 }`), 151 UserDataV3: conf.Ignition(`{ 152 "ignition": { 153 "version": "3.0.0" 154 }, 155 "storage": { 156 "files": [ 157 { 158 "path": "/var/resource/http", 159 "contents": { 160 "source": "http://s3-us-west-2.amazonaws.com/kola-fixtures/resources/anonymous" 161 }, 162 "mode": 420 163 }, 164 { 165 "path": "/var/resource/https", 166 "contents": { 167 "source": "https://s3-us-west-2.amazonaws.com/kola-fixtures/resources/anonymous" 168 }, 169 "mode": 420 170 }, 171 { 172 "path": "/var/resource/s3-anon", 173 "contents": { 174 "source": "s3://kola-fixtures/resources/anonymous" 175 }, 176 "mode": 420 177 } 178 ] 179 } 180 }`), 181 Distros: []string{"cl", "fcos", "rhcos"}, 182 }) 183 register.Register(®ister.Test{ 184 Name: "coreos.ignition.resource.s3", 185 Run: resourceS3, 186 ClusterSize: 1, 187 Platforms: []string{"aws"}, 188 UserData: conf.Ignition(`{ 189 "ignition": { 190 "version": "2.1.0", 191 "config": { 192 "append": [{ 193 "source": "s3://kola-fixtures/resources/authenticated-var.ign" 194 }] 195 } 196 }, 197 "storage": { 198 "files": [ 199 { 200 "filesystem": "root", 201 "path": "/var/resource/s3-auth", 202 "contents": { 203 "source": "s3://kola-fixtures/resources/authenticated" 204 }, 205 "mode": 420 206 } 207 ] 208 } 209 }`), 210 UserDataV3: conf.Ignition(`{ 211 "ignition": { 212 "version": "3.0.0", 213 "config": { 214 "merge": [{ 215 "source": "s3://kola-fixtures/resources/authenticated-var-v3.ign" 216 }] 217 } 218 }, 219 "storage": { 220 "files": [ 221 { 222 "path": "/var/resource/s3-auth", 223 "contents": { 224 "source": "s3://kola-fixtures/resources/authenticated" 225 }, 226 "mode": 420 227 } 228 ] 229 } 230 }`), 231 Distros: []string{"cl", "fcos", "rhcos"}, 232 }) 233 // TODO: once Ignition supports this on all channels/distros 234 // this test should be rolled into coreos.ignition.resources.remote 235 // Test specifically for versioned s3 objects 236 register.Register(®ister.Test{ 237 Name: "coreos.ignition.resource.s3.versioned", 238 Run: resourceS3Versioned, 239 ClusterSize: 1, 240 Flags: []register.Flag{register.RequiresInternetAccess}, 241 // https://github.com/coreos/bugs/issues/2205 for DO 242 ExcludePlatforms: []string{"do"}, 243 MinVersion: semver.Version{Major: 1995}, 244 UserData: conf.Ignition(`{ 245 "ignition": { 246 "version": "2.1.0" 247 }, 248 "storage": { 249 "files": [ 250 { 251 "filesystem": "root", 252 "path": "/var/resource/original", 253 "contents": { 254 "source": "http://s3-us-west-2.amazonaws.com/kola-fixtures/resources/versioned?versionId=null" 255 }, 256 "mode": 420 257 }, 258 { 259 "filesystem": "root", 260 "path": "/var/resource/latest", 261 "contents": { 262 "source": "http://s3-us-west-2.amazonaws.com/kola-fixtures/resources/versioned?versionId=RDWqxfnlcJOSDf1.5jy6ZP.oK9Bt7_Id" 263 }, 264 "mode": 420 265 } 266 ] 267 } 268 }`), 269 UserDataV3: conf.Ignition(`{ 270 "ignition": { 271 "version": "3.0.0" 272 }, 273 "storage": { 274 "files": [ 275 { 276 "path": "/var/resource/original", 277 "contents": { 278 "source": "http://s3-us-west-2.amazonaws.com/kola-fixtures/resources/versioned?versionId=null" 279 }, 280 "mode": 420 281 }, 282 { 283 "path": "/var/resource/latest", 284 "contents": { 285 "source": "http://s3-us-west-2.amazonaws.com/kola-fixtures/resources/versioned?versionId=RDWqxfnlcJOSDf1.5jy6ZP.oK9Bt7_Id" 286 }, 287 "mode": 420 288 } 289 ] 290 } 291 }`), 292 Distros: []string{"cl", "rhcos"}, 293 }) 294 } 295 296 func resourceLocal(c cluster.TestCluster) { 297 server := c.Machines()[0] 298 299 c.MustSSH(server, fmt.Sprintf("sudo systemd-run --quiet ./kolet run %s Serve", c.H.Name())) 300 301 ip := server.PrivateIP() 302 if c.Platform() == packet.Platform { 303 // private IP not configured in the initramfs 304 ip = server.IP() 305 } 306 307 var conf *conf.UserData 308 switch c.IgnitionVersion() { 309 case "v2": 310 conf = localClient 311 case "v3": 312 conf = localClientV3 313 default: 314 c.Fatal("unknown ignition version") 315 } 316 317 client, err := c.NewMachine(conf.Subst("$IP", ip)) 318 if err != nil { 319 c.Fatalf("starting client: %v", err) 320 } 321 322 checkResources(c, client, map[string]string{ 323 "data": "kola-data", 324 "http": "kola-http", 325 "tftp": "kola-tftp", 326 }) 327 } 328 329 func resourceRemote(c cluster.TestCluster) { 330 m := c.Machines()[0] 331 332 checkResources(c, m, map[string]string{ 333 "http": "kola-anonymous", 334 "https": "kola-anonymous", 335 "s3-anon": "kola-anonymous", 336 }) 337 } 338 339 func resourceS3(c cluster.TestCluster) { 340 m := c.Machines()[0] 341 342 checkResources(c, m, map[string]string{ 343 // object accessible by any authenticated S3 user, such as 344 // the IAM role associated with the instance 345 "s3-auth": "kola-authenticated", 346 // object created by configuration accessible by any authenticated 347 // S3 user, such as the IAM role associated with the instance 348 "s3-config": "kola-config", 349 }) 350 351 // verify that the objects are inaccessible anonymously 352 for _, objectName := range []string{"authenticated", "authenticated.ign"} { 353 _, _, err := m.SSH("curl -sf https://s3-us-west-2.amazonaws.com/kola-fixtures/resources/" + objectName) 354 if err == nil { 355 c.Fatal("anonymously fetching authenticated resource should have failed, but did not") 356 } 357 } 358 359 // ...but that the anonymous object is accessible 360 c.MustSSH(m, "curl -sf https://s3-us-west-2.amazonaws.com/kola-fixtures/resources/anonymous") 361 } 362 363 func resourceS3Versioned(c cluster.TestCluster) { 364 m := c.Machines()[0] 365 366 checkResources(c, m, map[string]string{ 367 "original": "original", 368 "latest": "updated", 369 }) 370 } 371 372 func checkResources(c cluster.TestCluster, m platform.Machine, resources map[string]string) { 373 for filename, expectedContents := range resources { 374 contents := c.MustSSH(m, fmt.Sprintf("sudo cat /var/resource/%s", filename)) 375 if string(contents) != expectedContents { 376 c.Fatalf("%s: %q != %q", filename, expectedContents, contents) 377 } 378 } 379 } 380 381 func Serve() error { 382 go func() { 383 http.HandleFunc("/http", func(w http.ResponseWriter, r *http.Request) { 384 w.Header().Add("Content-Type", "text/plain") 385 w.Write([]byte("kola-http")) 386 }) 387 err := http.ListenAndServe(":80", nil) 388 fmt.Println(err) 389 }() 390 391 go func() { 392 readHandler := func(filename string, r io.ReaderFrom) error { 393 switch filename { 394 case "/tftp": 395 r.ReadFrom(bytes.NewBufferString("kola-tftp")) 396 default: 397 return fmt.Errorf("404 not found") 398 } 399 return nil 400 } 401 server := tftp.NewServer(readHandler, nil) 402 err := server.ListenAndServe(":69") 403 fmt.Println(err) 404 }() 405 406 select {} 407 }