mirror of https://github.com/minio/minio.git
				
				
				
			feat: update binary once and push it to other servers (#15407)
This commit is contained in:
		
							parent
							
								
									916f274c83
								
							
						
					
					
						commit
						8ec888d13d
					
				|  | @ -142,7 +142,16 @@ func (a adminAPIHandlers) ServerUpdateHandler(w http.ResponseWriter, r *http.Req | |||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	for _, nerr := range globalNotificationSys.DownloadBinary(ctx, u, sha256Sum, releaseInfo) { | ||||
| 	// Download Binary Once
 | ||||
| 	reader, err := downloadBinary(u, mode) | ||||
| 	if err != nil { | ||||
| 		logger.LogIf(ctx, fmt.Errorf("server update failed with %w", err)) | ||||
| 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// Push binary to other servers
 | ||||
| 	for _, nerr := range globalNotificationSys.VerifyBinary(ctx, u, sha256Sum, releaseInfo, reader) { | ||||
| 		if nerr.Err != nil { | ||||
| 			err := AdminError{ | ||||
| 				Code:       AdminUpdateApplyFailure, | ||||
|  | @ -156,7 +165,7 @@ func (a adminAPIHandlers) ServerUpdateHandler(w http.ResponseWriter, r *http.Req | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	err = downloadBinary(u, sha256Sum, releaseInfo, mode) | ||||
| 	err = verifyBinary(u, sha256Sum, releaseInfo, mode, reader) | ||||
| 	if err != nil { | ||||
| 		logger.LogIf(ctx, fmt.Errorf("server update failed with %w", err)) | ||||
| 		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) | ||||
|  |  | |||
|  | @ -356,8 +356,8 @@ func (sys *NotificationSys) DownloadProfilingData(ctx context.Context, writer io | |||
| 	return | ||||
| } | ||||
| 
 | ||||
| // DownloadBinary - asks remote peers to download a new binary from the URL and to verify the checksum
 | ||||
| func (sys *NotificationSys) DownloadBinary(ctx context.Context, u *url.URL, sha256Sum []byte, releaseInfo string) []NotificationPeerErr { | ||||
| // VerifyBinary - asks remote peers to verify the checksum
 | ||||
| func (sys *NotificationSys) VerifyBinary(ctx context.Context, u *url.URL, sha256Sum []byte, releaseInfo string, reader []byte) []NotificationPeerErr { | ||||
| 	ng := WithNPeers(len(sys.peerClients)) | ||||
| 	for idx, client := range sys.peerClients { | ||||
| 		if client == nil { | ||||
|  | @ -365,7 +365,7 @@ func (sys *NotificationSys) DownloadBinary(ctx context.Context, u *url.URL, sha2 | |||
| 		} | ||||
| 		client := client | ||||
| 		ng.Go(ctx, func() error { | ||||
| 			return client.DownloadBinary(ctx, u, sha256Sum, releaseInfo) | ||||
| 			return client.VerifyBinary(ctx, u, sha256Sum, releaseInfo, reader) | ||||
| 		}, idx, *client.host) | ||||
| 	} | ||||
| 	return ng.Wait() | ||||
|  |  | |||
|  | @ -422,16 +422,18 @@ type binaryInfo struct { | |||
| 	URL         *url.URL | ||||
| 	Sha256Sum   []byte | ||||
| 	ReleaseInfo string | ||||
| 	BinaryFile  []byte | ||||
| } | ||||
| 
 | ||||
| // DownloadBinary - sends download binary message to remote peers.
 | ||||
| func (client *peerRESTClient) DownloadBinary(ctx context.Context, u *url.URL, sha256Sum []byte, releaseInfo string) error { | ||||
| // VerifyBinary - sends verify binary message to remote peers.
 | ||||
| func (client *peerRESTClient) VerifyBinary(ctx context.Context, u *url.URL, sha256Sum []byte, releaseInfo string, readerInput []byte) error { | ||||
| 	values := make(url.Values) | ||||
| 	var reader bytes.Buffer | ||||
| 	if err := gob.NewEncoder(&reader).Encode(binaryInfo{ | ||||
| 		URL:         u, | ||||
| 		Sha256Sum:   sha256Sum, | ||||
| 		ReleaseInfo: releaseInfo, | ||||
| 		BinaryFile:  readerInput, | ||||
| 	}); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  |  | |||
|  | @ -770,7 +770,7 @@ func (s *peerRESTServer) DownloadBinaryHandler(w http.ResponseWriter, r *http.Re | |||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if err = downloadBinary(info.URL, info.Sha256Sum, info.ReleaseInfo, getMinioMode()); err != nil { | ||||
| 	if err = verifyBinary(info.URL, info.Sha256Sum, info.ReleaseInfo, getMinioMode(), info.BinaryFile); err != nil { | ||||
| 		s.writeErrorResponse(w, err) | ||||
| 		return | ||||
| 	} | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ package cmd | |||
| 
 | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"bytes" | ||||
| 	"crypto" | ||||
| 	"crypto/tls" | ||||
| 	"encoding/hex" | ||||
|  | @ -505,26 +506,38 @@ func getUpdateReaderFromURL(u *url.URL, transport http.RoundTripper, mode string | |||
| 
 | ||||
| var updateInProgress uint32 | ||||
| 
 | ||||
| func downloadBinary(u *url.URL, sha256Sum []byte, releaseInfo string, mode string) (err error) { | ||||
| // Function to get the reader from an architecture
 | ||||
| func downloadBinary(u *url.URL, mode string) (readerReturn []byte, err error) { | ||||
| 	transport := getUpdateTransport(30 * time.Second) | ||||
| 	var reader io.ReadCloser | ||||
| 	if u.Scheme == "https" || u.Scheme == "http" { | ||||
| 		reader, err = getUpdateReaderFromURL(u, transport, mode) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} else { | ||||
| 		reader, err = getUpdateReaderFromFile(u) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// convert a Reader to bytes
 | ||||
| 	binaryFile, err := ioutil.ReadAll(reader) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return binaryFile, nil | ||||
| } | ||||
| 
 | ||||
| func verifyBinary(u *url.URL, sha256Sum []byte, releaseInfo string, mode string, reader []byte) (err error) { | ||||
| 	if !atomic.CompareAndSwapUint32(&updateInProgress, 0, 1) { | ||||
| 		return errors.New("update already in progress") | ||||
| 	} | ||||
| 	defer atomic.StoreUint32(&updateInProgress, 0) | ||||
| 
 | ||||
| 	transport := getUpdateTransport(30 * time.Second) | ||||
| 	var reader io.ReadCloser | ||||
| 	if u.Scheme == "https" || u.Scheme == "http" { | ||||
| 		reader, err = getUpdateReaderFromURL(u, transport, mode) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} else { | ||||
| 		reader, err = getUpdateReaderFromFile(u) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	opts := selfupdate.Options{ | ||||
| 		Hash:     crypto.SHA256, | ||||
| 		Checksum: sha256Sum, | ||||
|  | @ -552,7 +565,7 @@ func downloadBinary(u *url.URL, sha256Sum []byte, releaseInfo string, mode strin | |||
| 		opts.Verifier = v | ||||
| 	} | ||||
| 
 | ||||
| 	if err = selfupdate.PrepareAndCheckBinary(reader, opts); err != nil { | ||||
| 	if err = selfupdate.PrepareAndCheckBinary(bytes.NewReader(reader), opts); err != nil { | ||||
| 		var pathErr *os.PathError | ||||
| 		if errors.As(err, &pathErr) { | ||||
| 			return AdminError{ | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue