func (up *Uploader) uploadNode(n *node) (*client.PutResult, error) { fi := n.fi mode := fi.Mode() if mode&os.ModeType == 0 { return up.uploadNodeRegularFile(n) } m := schema.NewCommonFileMap(n.fullPath, fi) switch { case mode&os.ModeSymlink != 0: // TODO(bradfitz): use VFS here; not os.Readlink target, err := os.Readlink(n.fullPath) if err != nil { return nil, err } m.SetSymlinkTarget(target) case mode&os.ModeDevice != 0: // including mode & os.ModeCharDevice fallthrough case mode&os.ModeSocket != 0: fallthrough case mode&os.ModeNamedPipe != 0: // FIFO fallthrough default: return nil, schema.ErrUnimplemented case fi.IsDir(): ss := new(schema.StaticSet) for _, c := range n.children { pr, err := c.PutResult() if err != nil { return nil, fmt.Errorf("Error populating directory static set for child %q: %v", c.fullPath, err) } ss.Add(pr.BlobRef) } sspr, err := up.UploadMap(ss.Map()) if err != nil { return nil, err } schema.PopulateDirectoryMap(m, sspr.BlobRef) } mappr, err := up.UploadMap(m) if err == nil { if !mappr.Skipped { vlog.Printf("Uploaded %q, %s for %s", m["camliType"], mappr.BlobRef, n.fullPath) } } else { vlog.Printf("Error uploading map %v: %v", m, err) } return mappr, err }
func (up *Uploader) uploadNode(n *node) (*client.PutResult, error) { fi := n.fi m := schema.NewCommonFileMap(n.fullPath, fi) mode := fi.Mode() switch { case mode&os.ModeSymlink != 0: // TODO(bradfitz): use VFS here; PopulateSymlinkMap uses os.Readlink directly. if err := schema.PopulateSymlinkMap(m, n.fullPath); err != nil { return nil, err } case mode&os.ModeDevice != 0: // including mode & os.ModeCharDevice fallthrough case mode&os.ModeSocket != 0: fallthrough case mode&os.ModeNamedPipe != 0: // FIFO fallthrough default: return nil, schema.ErrUnimplemented case mode&os.ModeType == 0: // regular file m["camliType"] = "file" file, err := up.open(n.fullPath) if err != nil { return nil, err } defer file.Close() statReceiver := up.altStatReceiver if statReceiver == nil { // TODO(bradfitz): just make Client be a // StatReceiver? move remote's ReceiveBlob -> // Upload wrapper into Client itself? statReceiver = remote.NewFromClient(up.Client) } schemaWriteFileMap := schema.WriteFileMap if up.rollSplits { schemaWriteFileMap = schema.WriteFileMapRolling } blobref, err := schemaWriteFileMap(statReceiver, m, io.LimitReader(file, fi.Size())) if err != nil { return nil, err } // TODO(bradfitz): taking a PutResult here is kinda // gross. should instead make a blobserver.Storage // wrapper type that can track some of this? or that // updates the client stats directly or something. { json, _ := schema.MapToCamliJSON(m) pr := &client.PutResult{BlobRef: blobref, Size: int64(len(json)), Skipped: false} return pr, nil } case fi.IsDir(): ss := new(schema.StaticSet) for _, c := range n.children { pr, err := c.PutResult() if err != nil { return nil, fmt.Errorf("Error populating directory static set for child %q: %v", c.fullPath, err) } ss.Add(pr.BlobRef) } sspr, err := up.UploadMap(ss.Map()) if err != nil { return nil, err } schema.PopulateDirectoryMap(m, sspr.BlobRef) } mappr, err := up.UploadMap(m) if err == nil { if !mappr.Skipped { vlog.Printf("Uploaded %q, %s for %s", m["camliType"], mappr.BlobRef, n.fullPath) } } else { vlog.Printf("Error uploading map %v: %v", m, err) } return mappr, err }