github.com/cs3org/reva/v2@v2.27.7/pkg/storage/migrate/metadata.go (about) 1 // Copyright 2018-2021 CERN 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 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package migrate 20 21 import ( 22 "bufio" 23 "context" 24 "encoding/json" 25 "log" 26 "os" 27 "path" 28 "strconv" 29 "strings" 30 31 gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" 32 rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" 33 storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" 34 ) 35 36 // metaData representation in the import data 37 type metaData struct { 38 Type string `json:"type"` 39 Path string `json:"path"` 40 Etag string `json:"eTag"` 41 Permissions int `json:"permissions"` 42 MTime int `json:"mtime"` 43 } 44 45 // ImportMetadata from a files.jsonl file in exportPath. The files must already be present on the storage 46 // Will set etag and mtime 47 func ImportMetadata(ctx context.Context, client gateway.GatewayAPIClient, exportPath string, ns string) error { 48 49 filesJSONL, err := os.Open(path.Join(exportPath, "files.jsonl")) 50 if err != nil { 51 return err 52 } 53 jsonLines := bufio.NewScanner(filesJSONL) 54 filesJSONL.Close() 55 56 for jsonLines.Scan() { 57 var fileData metaData 58 if err := json.Unmarshal(jsonLines.Bytes(), &fileData); err != nil { 59 log.Fatal(err) 60 return err 61 } 62 63 m := make(map[string]string) 64 if fileData.Etag != "" { 65 // TODO sanitize etag? eg double quotes at beginning and end? 66 m["etag"] = fileData.Etag 67 } 68 if fileData.MTime != 0 { 69 m["mtime"] = strconv.Itoa(fileData.MTime) 70 } 71 // TODO permissions? is done via share? but this is owner permissions 72 73 if len(m) > 0 { 74 resourcePath := path.Join(ns, path.Base(exportPath), strings.TrimPrefix(fileData.Path, "/files/")) 75 samReq := &storageprovider.SetArbitraryMetadataRequest{ 76 Ref: &storageprovider.Reference{Path: resourcePath}, 77 ArbitraryMetadata: &storageprovider.ArbitraryMetadata{ 78 Metadata: m, 79 }, 80 } 81 samResp, err := client.SetArbitraryMetadata(ctx, samReq) 82 if err != nil { 83 log.Fatal(err) 84 } 85 86 if samResp.Status.Code == rpc.Code_CODE_NOT_FOUND { 87 log.Print("File does not exist on target system, skipping metadata import: " + resourcePath) 88 } 89 if samResp.Status.Code != rpc.Code_CODE_OK { 90 log.Print("Error importing metadata, skipping metadata import: " + resourcePath + ", " + samResp.Status.Message) 91 } 92 } else { 93 log.Print("no etag or mtime for : " + fileData.Path) 94 } 95 96 } 97 return nil 98 }