func handleContainerVerify(w http.ResponseWriter, r *http.Request) { uid, err := types.NewUUID(r.FormValue("uid")) if err != nil { w.WriteHeader(http.StatusBadRequest) fmt.Fprintf(w, "uid field missing or malformed: %v", err) return } sig, err := base64.StdEncoding.DecodeString(r.FormValue("signature")) if err != nil { w.WriteHeader(http.StatusBadRequest) fmt.Fprintf(w, "signature field missing or corrupt: %v", err) return } digest := sig[:sha256.Size] sum := sig[sha256.Size:] h := hmac.New(sha256.New, hmacKey[:]) h.Write(uid[:]) h.Write(digest) if hmac.Equal(sum, h.Sum(nil)) { w.WriteHeader(http.StatusOK) } else { w.WriteHeader(http.StatusForbidden) } }
func handleRegisterApp(w http.ResponseWriter, r *http.Request) { remoteIP := strings.Split(r.RemoteAddr, ":")[0] if _, ok := metadataByIP[remoteIP]; ok { // not allowed from container IP w.WriteHeader(http.StatusForbidden) return } uid, err := types.NewUUID(mux.Vars(r)["uid"]) if err != nil { w.WriteHeader(http.StatusNotFound) fmt.Fprintf(w, "UUID is missing or mulformed: %v", err) return } m, ok := metadataByUID[*uid] if !ok { w.WriteHeader(http.StatusNotFound) fmt.Fprint(w, "Container with given UUID not found") return } an := mux.Vars(r)["app"] app := &schema.AppManifest{} if err := json.NewDecoder(r.Body).Decode(&app); err != nil { w.WriteHeader(http.StatusBadRequest) fmt.Fprintf(w, "JSON-decoding failed: %v", err) return } m.apps[an] = app w.WriteHeader(http.StatusOK) }
// Setup sets up a filesystem for a container based on the given config. // The directory containing the filesystem is returned, and any error encountered. func Setup(cfg Config) (string, error) { if cfg.Debug { log.SetOutput(os.Stderr) } cuuid, err := types.NewUUID(uuid.New()) if err != nil { return "", fmt.Errorf("error creating UID: %v", err) } // TODO(jonboulle): collision detection/mitigation // Create a directory for this container dir := filepath.Join(cfg.ContainersDir, cuuid.String()) if err := os.MkdirAll(dir, 0700); err != nil { return "", fmt.Errorf("error creating directory: %v", err) } log.Printf("Unpacking stage1 rootfs") if cfg.Stage1Rootfs != "" { err = unpackRootfs(cfg.Stage1Rootfs, rktpath.Stage1RootfsPath(dir)) } else { err = unpackBuiltinRootfs(rktpath.Stage1RootfsPath(dir)) } if err != nil { return "", fmt.Errorf("error unpacking rootfs: %v", err) } log.Printf("Writing stage1 init") var in io.Reader if cfg.Stage1Init != "" { in, err = os.Open(cfg.Stage1Init) if err != nil { return "", fmt.Errorf("error loading stage1 init binary: %v", err) } } else { init_bin, err := stage1_init.Asset("s1init") if err != nil { return "", fmt.Errorf("error accessing stage1 init bindata: %v", err) } in = bytes.NewBuffer(init_bin) } fn := filepath.Join(dir, initPath) out, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY, 0555) if err != nil { return "", fmt.Errorf("error opening stage1 init for writing: %v", err) } if _, err := io.Copy(out, in); err != nil { return "", fmt.Errorf("error writing stage1 init: %v", err) } if err := out.Close(); err != nil { return "", fmt.Errorf("error closing stage1 init: %v", err) } log.Printf("Wrote filesystem to %s\n", dir) cm := schema.ContainerRuntimeManifest{ ACKind: "ContainerRuntimeManifest", UUID: *cuuid, Apps: make(schema.AppList, 0), } v, err := types.NewSemVer(version.Version) if err != nil { return "", fmt.Errorf("error creating version: %v", err) } cm.ACVersion = *v for _, img := range cfg.Images { am, err := setupImage(cfg, img, dir) if err != nil { return "", fmt.Errorf("error setting up image %s: %v", img, err) } if cm.Apps.Get(am.Name) != nil { return "", fmt.Errorf("error: multiple apps with name %s", am.Name) } a := schema.App{ Name: am.Name, ImageID: img, Isolators: am.Isolators, Annotations: am.Annotations, } cm.Apps = append(cm.Apps, a) } var sVols []types.Volume for key, path := range cfg.Volumes { v := types.Volume{ Kind: "host", Source: path, ReadOnly: true, Fulfills: []types.ACName{ types.ACName(key), }, } sVols = append(sVols, v) } // TODO(jonboulle): check that app mountpoint expectations are // satisfied here, rather than waiting for stage1 cm.Volumes = sVols cdoc, err := json.Marshal(cm) if err != nil { return "", fmt.Errorf("error marshalling container manifest: %v", err) } log.Printf("Writing container manifest") fn = rktpath.ContainerManifestPath(dir) if err := ioutil.WriteFile(fn, cdoc, 0700); err != nil { return "", fmt.Errorf("error writing container manifest: %v", err) } return dir, nil }