| 
									
										
										
										
											2017-04-14 10:29:00 +02:00
										 |  |  | // Copyright 2017 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | // This file is part of go-ethereum. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // go-ethereum is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // go-ethereum is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							|  |  |  | // GNU General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Command  MANIFEST update | 
					
						
							|  |  |  | package main | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2017-02-22 14:10:07 +02:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2017-02-22 14:10:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 15:06:16 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/cmd/utils" | 
					
						
							| 
									
										
										
										
											2017-04-06 23:22:22 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/swarm/api" | 
					
						
							| 
									
										
										
										
											2017-04-04 23:20:07 +01:00
										 |  |  | 	swarm "github.com/ethereum/go-ethereum/swarm/api/client" | 
					
						
							| 
									
										
										
										
											2017-02-22 14:10:07 +02:00
										 |  |  | 	"gopkg.in/urfave/cli.v1" | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-12 14:51:38 +02:00
										 |  |  | var manifestCommand = cli.Command{ | 
					
						
							|  |  |  | 	Name:               "manifest", | 
					
						
							|  |  |  | 	CustomHelpTemplate: helpTemplate, | 
					
						
							|  |  |  | 	Usage:              "perform operations on swarm manifests", | 
					
						
							|  |  |  | 	ArgsUsage:          "COMMAND", | 
					
						
							|  |  |  | 	Description:        "Updates a MANIFEST by adding/removing/updating the hash of a path.\nCOMMAND could be: add, update, remove", | 
					
						
							|  |  |  | 	Subcommands: []cli.Command{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			Action:             manifestAdd, | 
					
						
							|  |  |  | 			CustomHelpTemplate: helpTemplate, | 
					
						
							|  |  |  | 			Name:               "add", | 
					
						
							|  |  |  | 			Usage:              "add a new path to the manifest", | 
					
						
							|  |  |  | 			ArgsUsage:          "<MANIFEST> <path> <hash>", | 
					
						
							|  |  |  | 			Description:        "Adds a new path to the manifest", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			Action:             manifestUpdate, | 
					
						
							|  |  |  | 			CustomHelpTemplate: helpTemplate, | 
					
						
							|  |  |  | 			Name:               "update", | 
					
						
							|  |  |  | 			Usage:              "update the hash for an already existing path in the manifest", | 
					
						
							|  |  |  | 			ArgsUsage:          "<MANIFEST> <path> <newhash>", | 
					
						
							|  |  |  | 			Description:        "Update the hash for an already existing path in the manifest", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			Action:             manifestRemove, | 
					
						
							|  |  |  | 			CustomHelpTemplate: helpTemplate, | 
					
						
							|  |  |  | 			Name:               "remove", | 
					
						
							|  |  |  | 			Usage:              "removes a path from the manifest", | 
					
						
							|  |  |  | 			ArgsUsage:          "<MANIFEST> <path>", | 
					
						
							|  |  |  | 			Description:        "Removes a path from the manifest", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | // manifestAdd adds a new entry to the manifest at the given path. | 
					
						
							|  |  |  | // New entry hash, the last argument, must be the hash of a manifest | 
					
						
							|  |  |  | // with only one entry, which meta-data will be added to the original manifest. | 
					
						
							|  |  |  | // On success, this function will print new (updated) manifest's hash. | 
					
						
							|  |  |  | func manifestAdd(ctx *cli.Context) { | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	args := ctx.Args() | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	if len(args) != 3 { | 
					
						
							|  |  |  | 		utils.Fatalf("Need exactly three arguments <MHASH> <path> <HASH>") | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var ( | 
					
						
							| 
									
										
										
										
											2017-02-22 14:10:07 +02:00
										 |  |  | 		mhash = args[0] | 
					
						
							|  |  |  | 		path  = args[1] | 
					
						
							|  |  |  | 		hash  = args[2] | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	bzzapi := strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/") | 
					
						
							|  |  |  | 	client := swarm.NewClient(bzzapi) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m, _, err := client.DownloadManifest(hash) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		utils.Fatalf("Error downloading manifest to add: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	l := len(m.Entries) | 
					
						
							|  |  |  | 	if l == 0 { | 
					
						
							|  |  |  | 		utils.Fatalf("No entries in manifest %s", hash) | 
					
						
							|  |  |  | 	} else if l > 1 { | 
					
						
							|  |  |  | 		utils.Fatalf("Too many entries in manifest %s", hash) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	newManifest := addEntryToManifest(client, mhash, path, m.Entries[0]) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	fmt.Println(newManifest) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | // manifestUpdate replaces an existing entry of the manifest at the given path. | 
					
						
							|  |  |  | // New entry hash, the last argument, must be the hash of a manifest | 
					
						
							|  |  |  | // with only one entry, which meta-data will be added to the original manifest. | 
					
						
							|  |  |  | // On success, this function will print hash of the updated manifest. | 
					
						
							|  |  |  | func manifestUpdate(ctx *cli.Context) { | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	args := ctx.Args() | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	if len(args) != 3 { | 
					
						
							|  |  |  | 		utils.Fatalf("Need exactly three arguments <MHASH> <path> <HASH>") | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var ( | 
					
						
							| 
									
										
										
										
											2017-02-22 14:10:07 +02:00
										 |  |  | 		mhash = args[0] | 
					
						
							|  |  |  | 		path  = args[1] | 
					
						
							|  |  |  | 		hash  = args[2] | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	bzzapi := strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/") | 
					
						
							|  |  |  | 	client := swarm.NewClient(bzzapi) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	m, _, err := client.DownloadManifest(hash) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		utils.Fatalf("Error downloading manifest to update: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	l := len(m.Entries) | 
					
						
							|  |  |  | 	if l == 0 { | 
					
						
							|  |  |  | 		utils.Fatalf("No entries in manifest %s", hash) | 
					
						
							|  |  |  | 	} else if l > 1 { | 
					
						
							|  |  |  | 		utils.Fatalf("Too many entries in manifest %s", hash) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	newManifest, _, defaultEntryUpdated := updateEntryInManifest(client, mhash, path, m.Entries[0], true) | 
					
						
							|  |  |  | 	if defaultEntryUpdated { | 
					
						
							|  |  |  | 		// Print informational message to stderr | 
					
						
							|  |  |  | 		// allowing the user to get the new manifest hash from stdout | 
					
						
							|  |  |  | 		// without the need to parse the complete output. | 
					
						
							|  |  |  | 		fmt.Fprintln(os.Stderr, "Manifest default entry is updated, too") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	fmt.Println(newManifest) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | // manifestRemove removes an existing entry of the manifest at the given path. | 
					
						
							|  |  |  | // On success, this function will print hash of the manifest which does not | 
					
						
							|  |  |  | // contain the path. | 
					
						
							|  |  |  | func manifestRemove(ctx *cli.Context) { | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	args := ctx.Args() | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	if len(args) != 2 { | 
					
						
							|  |  |  | 		utils.Fatalf("Need exactly two arguments <MHASH> <path>") | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var ( | 
					
						
							| 
									
										
										
										
											2017-02-22 14:10:07 +02:00
										 |  |  | 		mhash = args[0] | 
					
						
							|  |  |  | 		path  = args[1] | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	bzzapi := strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/") | 
					
						
							|  |  |  | 	client := swarm.NewClient(bzzapi) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	newManifest := removeEntryFromManifest(client, mhash, path) | 
					
						
							|  |  |  | 	fmt.Println(newManifest) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | func addEntryToManifest(client *swarm.Client, mhash, path string, entry api.ManifestEntry) string { | 
					
						
							|  |  |  | 	var longestPathEntry = api.ManifestEntry{} | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 	mroot, isEncrypted, err := client.DownloadManifest(mhash) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-03-02 15:06:16 +02:00
										 |  |  | 		utils.Fatalf("Manifest download failed: %v", err) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// See if we path is in this Manifest or do we have to dig deeper | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	for _, e := range mroot.Entries { | 
					
						
							|  |  |  | 		if path == e.Path { | 
					
						
							| 
									
										
										
										
											2017-03-02 15:06:16 +02:00
										 |  |  | 			utils.Fatalf("Path %s already present, not adding anything", path) | 
					
						
							| 
									
										
										
										
											2017-02-22 14:10:07 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 			if e.ContentType == api.ManifestType { | 
					
						
							|  |  |  | 				prfxlen := strings.HasPrefix(path, e.Path) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 				if prfxlen && len(path) > len(longestPathEntry.Path) { | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 					longestPathEntry = e | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if longestPathEntry.Path != "" { | 
					
						
							|  |  |  | 		// Load the child Manifest add the entry there | 
					
						
							|  |  |  | 		newPath := path[len(longestPathEntry.Path):] | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 		newHash := addEntryToManifest(client, longestPathEntry.Hash, newPath, entry) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Replace the hash for parent Manifests | 
					
						
							| 
									
										
										
										
											2017-04-06 23:22:22 +01:00
										 |  |  | 		newMRoot := &api.Manifest{} | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 		for _, e := range mroot.Entries { | 
					
						
							|  |  |  | 			if longestPathEntry.Path == e.Path { | 
					
						
							|  |  |  | 				e.Hash = newHash | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 			newMRoot.Entries = append(newMRoot.Entries, e) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 		} | 
					
						
							|  |  |  | 		mroot = newMRoot | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		// Add the entry in the leaf Manifest | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 		entry.Path = path | 
					
						
							|  |  |  | 		mroot.Entries = append(mroot.Entries, entry) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 	newManifestHash, err := client.UploadManifest(mroot, isEncrypted) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-03-02 15:06:16 +02:00
										 |  |  | 		utils.Fatalf("Manifest upload failed: %v", err) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	} | 
					
						
							|  |  |  | 	return newManifestHash | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | // updateEntryInManifest updates an existing entry o path with a new one in the manifest with provided mhash | 
					
						
							|  |  |  | // finding the path recursively through all nested manifests. Argument isRoot is used for default | 
					
						
							|  |  |  | // entry update detection. If the updated entry has the same hash as the default entry, then the | 
					
						
							|  |  |  | // default entry in root manifest will be updated too. | 
					
						
							|  |  |  | // Returned values are the new manifest hash, hash of the entry that was replaced by the new entry and | 
					
						
							|  |  |  | // a a bool that is true if default entry is updated. | 
					
						
							|  |  |  | func updateEntryInManifest(client *swarm.Client, mhash, path string, entry api.ManifestEntry, isRoot bool) (newManifestHash, oldHash string, defaultEntryUpdated bool) { | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	var ( | 
					
						
							| 
									
										
										
										
											2017-04-06 23:22:22 +01:00
										 |  |  | 		newEntry         = api.ManifestEntry{} | 
					
						
							|  |  |  | 		longestPathEntry = api.ManifestEntry{} | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 	mroot, isEncrypted, err := client.DownloadManifest(mhash) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-03-02 15:06:16 +02:00
										 |  |  | 		utils.Fatalf("Manifest download failed: %v", err) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// See if we path is in this Manifest or do we have to dig deeper | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	for _, e := range mroot.Entries { | 
					
						
							|  |  |  | 		if path == e.Path { | 
					
						
							|  |  |  | 			newEntry = e | 
					
						
							|  |  |  | 			// keep the reference of the hash of the entry that should be replaced | 
					
						
							|  |  |  | 			// for default entry detection | 
					
						
							|  |  |  | 			oldHash = e.Hash | 
					
						
							| 
									
										
										
										
											2017-02-22 14:10:07 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 			if e.ContentType == api.ManifestType { | 
					
						
							|  |  |  | 				prfxlen := strings.HasPrefix(path, e.Path) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 				if prfxlen && len(path) > len(longestPathEntry.Path) { | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 					longestPathEntry = e | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if longestPathEntry.Path == "" && newEntry.Path == "" { | 
					
						
							| 
									
										
										
										
											2017-03-02 15:06:16 +02:00
										 |  |  | 		utils.Fatalf("Path %s not present in the Manifest, not setting anything", path) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if longestPathEntry.Path != "" { | 
					
						
							|  |  |  | 		// Load the child Manifest add the entry there | 
					
						
							|  |  |  | 		newPath := path[len(longestPathEntry.Path):] | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 		var newHash string | 
					
						
							|  |  |  | 		newHash, oldHash, _ = updateEntryInManifest(client, longestPathEntry.Hash, newPath, entry, false) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Replace the hash for parent Manifests | 
					
						
							| 
									
										
										
										
											2017-04-06 23:22:22 +01:00
										 |  |  | 		newMRoot := &api.Manifest{} | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 		for _, e := range mroot.Entries { | 
					
						
							|  |  |  | 			if longestPathEntry.Path == e.Path { | 
					
						
							|  |  |  | 				e.Hash = newHash | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 			newMRoot.Entries = append(newMRoot.Entries, e) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		mroot = newMRoot | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	// update the manifest if the new entry is found and | 
					
						
							|  |  |  | 	// check if default entry should be updated | 
					
						
							|  |  |  | 	if newEntry.Path != "" || isRoot { | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 		// Replace the hash for leaf Manifest | 
					
						
							| 
									
										
										
										
											2017-04-06 23:22:22 +01:00
										 |  |  | 		newMRoot := &api.Manifest{} | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 		for _, e := range mroot.Entries { | 
					
						
							|  |  |  | 			if newEntry.Path == e.Path { | 
					
						
							|  |  |  | 				entry.Path = e.Path | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 				newMRoot.Entries = append(newMRoot.Entries, entry) | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 			} else if isRoot && e.Path == "" && e.Hash == oldHash { | 
					
						
							|  |  |  | 				entry.Path = e.Path | 
					
						
							|  |  |  | 				newMRoot.Entries = append(newMRoot.Entries, entry) | 
					
						
							|  |  |  | 				defaultEntryUpdated = true | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				newMRoot.Entries = append(newMRoot.Entries, e) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		mroot = newMRoot | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	newManifestHash, err = client.UploadManifest(mroot, isEncrypted) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-03-02 15:06:16 +02:00
										 |  |  | 		utils.Fatalf("Manifest upload failed: %v", err) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	return newManifestHash, oldHash, defaultEntryUpdated | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | func removeEntryFromManifest(client *swarm.Client, mhash, path string) string { | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	var ( | 
					
						
							| 
									
										
										
										
											2017-04-06 23:22:22 +01:00
										 |  |  | 		entryToRemove    = api.ManifestEntry{} | 
					
						
							|  |  |  | 		longestPathEntry = api.ManifestEntry{} | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 	mroot, isEncrypted, err := client.DownloadManifest(mhash) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-03-02 15:06:16 +02:00
										 |  |  | 		utils.Fatalf("Manifest download failed: %v", err) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// See if we path is in this Manifest or do we have to dig deeper | 
					
						
							|  |  |  | 	for _, entry := range mroot.Entries { | 
					
						
							|  |  |  | 		if path == entry.Path { | 
					
						
							|  |  |  | 			entryToRemove = entry | 
					
						
							| 
									
										
										
										
											2017-02-22 14:10:07 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 			if entry.ContentType == api.ManifestType { | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 				prfxlen := strings.HasPrefix(path, entry.Path) | 
					
						
							|  |  |  | 				if prfxlen && len(path) > len(longestPathEntry.Path) { | 
					
						
							|  |  |  | 					longestPathEntry = entry | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if longestPathEntry.Path == "" && entryToRemove.Path == "" { | 
					
						
							| 
									
										
										
										
											2017-03-02 15:06:16 +02:00
										 |  |  | 		utils.Fatalf("Path %s not present in the Manifest, not removing anything", path) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if longestPathEntry.Path != "" { | 
					
						
							|  |  |  | 		// Load the child Manifest remove the entry there | 
					
						
							|  |  |  | 		newPath := path[len(longestPathEntry.Path):] | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 		newHash := removeEntryFromManifest(client, longestPathEntry.Hash, newPath) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Replace the hash for parent Manifests | 
					
						
							| 
									
										
										
										
											2017-04-06 23:22:22 +01:00
										 |  |  | 		newMRoot := &api.Manifest{} | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 		for _, entry := range mroot.Entries { | 
					
						
							|  |  |  | 			if longestPathEntry.Path == entry.Path { | 
					
						
							|  |  |  | 				entry.Hash = newHash | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			newMRoot.Entries = append(newMRoot.Entries, entry) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		mroot = newMRoot | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if entryToRemove.Path != "" { | 
					
						
							|  |  |  | 		// remove the entry in this Manifest | 
					
						
							| 
									
										
										
										
											2017-04-06 23:22:22 +01:00
										 |  |  | 		newMRoot := &api.Manifest{} | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 		for _, entry := range mroot.Entries { | 
					
						
							|  |  |  | 			if entryToRemove.Path != entry.Path { | 
					
						
							|  |  |  | 				newMRoot.Entries = append(newMRoot.Entries, entry) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		mroot = newMRoot | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 	newManifestHash, err := client.UploadManifest(mroot, isEncrypted) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-03-02 15:06:16 +02:00
										 |  |  | 		utils.Fatalf("Manifest upload failed: %v", err) | 
					
						
							| 
									
										
										
										
											2017-02-13 08:03:05 +05:30
										 |  |  | 	} | 
					
						
							|  |  |  | 	return newManifestHash | 
					
						
							|  |  |  | } |