mirror of
https://github.com/minio/minio.git
synced 2025-01-11 15:03:22 -05:00
fips build tag uses relevant binary link for updates (#12014)
This code is necessary for `mc admin update` command to work with fips compiled binaries, with fips tags the releaseInfo will automatically point to fips specific binaries.
This commit is contained in:
parent
835d2cb9a3
commit
641e564b65
@ -64,8 +64,8 @@ const (
|
|||||||
mgmtForceStop = "forceStop"
|
mgmtForceStop = "forceStop"
|
||||||
)
|
)
|
||||||
|
|
||||||
func updateServer(u *url.URL, sha256Sum []byte, lrTime time.Time, mode string) (us madmin.ServerUpdateStatus, err error) {
|
func updateServer(u *url.URL, sha256Sum []byte, lrTime time.Time, releaseInfo string, mode string) (us madmin.ServerUpdateStatus, err error) {
|
||||||
if err = doUpdate(u, lrTime, sha256Sum, mode); err != nil {
|
if err = doUpdate(u, lrTime, sha256Sum, releaseInfo, mode); err != nil {
|
||||||
return us, err
|
return us, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,14 +115,13 @@ func (a adminAPIHandlers) ServerUpdateHandler(w http.ResponseWriter, r *http.Req
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sha256Sum, lrTime, err := parseReleaseData(content)
|
sha256Sum, lrTime, releaseInfo, err := parseReleaseData(content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
u.Path = path.Dir(u.Path) + SlashSeparator + "minio.RELEASE." + lrTime.Format(minioReleaseTagTimeLayout)
|
u.Path = path.Dir(u.Path) + SlashSeparator + releaseInfo
|
||||||
|
|
||||||
crTime, err := GetCurrentReleaseTime()
|
crTime, err := GetCurrentReleaseTime()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||||
@ -146,7 +145,7 @@ func (a adminAPIHandlers) ServerUpdateHandler(w http.ResponseWriter, r *http.Req
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, nerr := range globalNotificationSys.ServerUpdate(ctx, u, sha256Sum, lrTime) {
|
for _, nerr := range globalNotificationSys.ServerUpdate(ctx, u, sha256Sum, lrTime, releaseInfo) {
|
||||||
if nerr.Err != nil {
|
if nerr.Err != nil {
|
||||||
logger.GetReqInfo(ctx).SetTags("peerAddress", nerr.Host.String())
|
logger.GetReqInfo(ctx).SetTags("peerAddress", nerr.Host.String())
|
||||||
logger.LogIf(ctx, nerr.Err)
|
logger.LogIf(ctx, nerr.Err)
|
||||||
@ -156,7 +155,7 @@ func (a adminAPIHandlers) ServerUpdateHandler(w http.ResponseWriter, r *http.Req
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStatus, err := updateServer(u, sha256Sum, lrTime, mode)
|
updateStatus, err := updateServer(u, sha256Sum, lrTime, releaseInfo, mode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Server update failed, please do not restart the servers yet: failed with %w", err)
|
err = fmt.Errorf("Server update failed, please do not restart the servers yet: failed with %w", err)
|
||||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||||
|
@ -400,7 +400,7 @@ func (sys *NotificationSys) DownloadProfilingData(ctx context.Context, writer io
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ServerUpdate - updates remote peers.
|
// ServerUpdate - updates remote peers.
|
||||||
func (sys *NotificationSys) ServerUpdate(ctx context.Context, u *url.URL, sha256Sum []byte, lrTime time.Time) []NotificationPeerErr {
|
func (sys *NotificationSys) ServerUpdate(ctx context.Context, u *url.URL, sha256Sum []byte, lrTime time.Time, releaseInfo string) []NotificationPeerErr {
|
||||||
ng := WithNPeers(len(sys.peerClients))
|
ng := WithNPeers(len(sys.peerClients))
|
||||||
for idx, client := range sys.peerClients {
|
for idx, client := range sys.peerClients {
|
||||||
if client == nil {
|
if client == nil {
|
||||||
@ -408,7 +408,7 @@ func (sys *NotificationSys) ServerUpdate(ctx context.Context, u *url.URL, sha256
|
|||||||
}
|
}
|
||||||
client := client
|
client := client
|
||||||
ng.Go(ctx, func() error {
|
ng.Go(ctx, func() error {
|
||||||
return client.ServerUpdate(ctx, u, sha256Sum, lrTime)
|
return client.ServerUpdate(ctx, u, sha256Sum, lrTime, releaseInfo)
|
||||||
}, idx, *client.host)
|
}, idx, *client.host)
|
||||||
}
|
}
|
||||||
return ng.Wait()
|
return ng.Wait()
|
||||||
|
@ -602,16 +602,18 @@ type serverUpdateInfo struct {
|
|||||||
URL *url.URL
|
URL *url.URL
|
||||||
Sha256Sum []byte
|
Sha256Sum []byte
|
||||||
Time time.Time
|
Time time.Time
|
||||||
|
ReleaseInfo string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerUpdate - sends server update message to remote peers.
|
// ServerUpdate - sends server update message to remote peers.
|
||||||
func (client *peerRESTClient) ServerUpdate(ctx context.Context, u *url.URL, sha256Sum []byte, lrTime time.Time) error {
|
func (client *peerRESTClient) ServerUpdate(ctx context.Context, u *url.URL, sha256Sum []byte, lrTime time.Time, releaseInfo string) error {
|
||||||
values := make(url.Values)
|
values := make(url.Values)
|
||||||
var reader bytes.Buffer
|
var reader bytes.Buffer
|
||||||
if err := gob.NewEncoder(&reader).Encode(serverUpdateInfo{
|
if err := gob.NewEncoder(&reader).Encode(serverUpdateInfo{
|
||||||
URL: u,
|
URL: u,
|
||||||
Sha256Sum: sha256Sum,
|
Sha256Sum: sha256Sum,
|
||||||
Time: lrTime,
|
Time: lrTime,
|
||||||
|
ReleaseInfo: releaseInfo,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -771,7 +771,7 @@ func (s *peerRESTServer) ServerUpdateHandler(w http.ResponseWriter, r *http.Requ
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err = updateServer(info.URL, info.Sha256Sum, info.Time, getMinioMode()); err != nil {
|
if _, err = updateServer(info.URL, info.Sha256Sum, info.Time, info.ReleaseInfo, getMinioMode()); err != nil {
|
||||||
s.writeErrorResponse(w, err)
|
s.writeErrorResponse(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// +build !fips
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MinIO Cloud Storage, (C) 2015-2020 MinIO, Inc.
|
* MinIO Cloud Storage, (C) 2015-2021 MinIO, Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -369,7 +371,7 @@ func downloadReleaseURL(u *url.URL, timeout time.Duration, mode string) (content
|
|||||||
// fbe246edbd382902db9a4035df7dce8cb441357d minio.RELEASE.2016-10-07T01-16-39Z.<hotfix_optional>
|
// fbe246edbd382902db9a4035df7dce8cb441357d minio.RELEASE.2016-10-07T01-16-39Z.<hotfix_optional>
|
||||||
//
|
//
|
||||||
// The second word must be `minio.` appended to a standard release tag.
|
// The second word must be `minio.` appended to a standard release tag.
|
||||||
func parseReleaseData(data string) (sha256Sum []byte, releaseTime time.Time, err error) {
|
func parseReleaseData(data string) (sha256Sum []byte, releaseTime time.Time, releaseInfo string, err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = AdminError{
|
err = AdminError{
|
||||||
@ -383,25 +385,25 @@ func parseReleaseData(data string) (sha256Sum []byte, releaseTime time.Time, err
|
|||||||
fields := strings.Fields(data)
|
fields := strings.Fields(data)
|
||||||
if len(fields) != 2 {
|
if len(fields) != 2 {
|
||||||
err = fmt.Errorf("Unknown release data `%s`", data)
|
err = fmt.Errorf("Unknown release data `%s`", data)
|
||||||
return sha256Sum, releaseTime, err
|
return sha256Sum, releaseTime, releaseInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sha256Sum, err = hex.DecodeString(fields[0])
|
sha256Sum, err = hex.DecodeString(fields[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return sha256Sum, releaseTime, err
|
return sha256Sum, releaseTime, releaseInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseInfo := fields[1]
|
releaseInfo = fields[1]
|
||||||
|
|
||||||
// Split release of style minio.RELEASE.2019-08-21T19-40-07Z.<hotfix>
|
// Split release of style minio.RELEASE.2019-08-21T19-40-07Z.<hotfix>
|
||||||
nfields := strings.SplitN(releaseInfo, ".", 2)
|
nfields := strings.SplitN(releaseInfo, ".", 2)
|
||||||
if len(nfields) != 2 {
|
if len(nfields) != 2 {
|
||||||
err = fmt.Errorf("Unknown release information `%s`", releaseInfo)
|
err = fmt.Errorf("Unknown release information `%s`", releaseInfo)
|
||||||
return sha256Sum, releaseTime, err
|
return sha256Sum, releaseTime, releaseInfo, err
|
||||||
}
|
}
|
||||||
if nfields[0] != "minio" {
|
if nfields[0] != "minio" {
|
||||||
err = fmt.Errorf("Unknown release `%s`", releaseInfo)
|
err = fmt.Errorf("Unknown release `%s`", releaseInfo)
|
||||||
return sha256Sum, releaseTime, err
|
return sha256Sum, releaseTime, releaseInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseTime, err = releaseTagToReleaseTime(nfields[1])
|
releaseTime, err = releaseTagToReleaseTime(nfields[1])
|
||||||
@ -409,7 +411,7 @@ func parseReleaseData(data string) (sha256Sum []byte, releaseTime time.Time, err
|
|||||||
err = fmt.Errorf("Unknown release tag format. %w", err)
|
err = fmt.Errorf("Unknown release tag format. %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return sha256Sum, releaseTime, err
|
return sha256Sum, releaseTime, releaseInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUpdateTransport(timeout time.Duration) http.RoundTripper {
|
func getUpdateTransport(timeout time.Duration) http.RoundTripper {
|
||||||
@ -433,7 +435,8 @@ func getLatestReleaseTime(u *url.URL, timeout time.Duration, mode string) (sha25
|
|||||||
return sha256Sum, releaseTime, err
|
return sha256Sum, releaseTime, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseReleaseData(data)
|
sha256Sum, releaseTime, _, err = parseReleaseData(data)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -516,7 +519,7 @@ func getUpdateReaderFromURL(u *url.URL, transport http.RoundTripper, mode string
|
|||||||
return resp.Body, nil
|
return resp.Body, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func doUpdate(u *url.URL, lrTime time.Time, sha256Sum []byte, mode string) (err error) {
|
func doUpdate(u *url.URL, lrTime time.Time, sha256Sum []byte, releaseInfo string, mode string) (err error) {
|
||||||
transport := getUpdateTransport(30 * time.Second)
|
transport := getUpdateTransport(30 * time.Second)
|
||||||
var reader io.ReadCloser
|
var reader io.ReadCloser
|
||||||
if u.Scheme == "https" || u.Scheme == "http" {
|
if u.Scheme == "https" || u.Scheme == "http" {
|
||||||
@ -539,7 +542,7 @@ func doUpdate(u *url.URL, lrTime time.Time, sha256Sum []byte, mode string) (err
|
|||||||
minisignPubkey := env.Get(envMinisignPubKey, "")
|
minisignPubkey := env.Get(envMinisignPubKey, "")
|
||||||
if minisignPubkey != "" {
|
if minisignPubkey != "" {
|
||||||
v := selfupdate.NewVerifier()
|
v := selfupdate.NewVerifier()
|
||||||
u.Path = path.Dir(u.Path) + slashSeparator + "minio.RELEASE." + lrTime.Format(minioReleaseTagTimeLayout) + ".minisig"
|
u.Path = path.Dir(u.Path) + slashSeparator + releaseInfo + ".minisig"
|
||||||
if err = v.LoadFromURL(u.String(), minisignPubkey, transport); err != nil {
|
if err = v.LoadFromURL(u.String(), minisignPubkey, transport); err != nil {
|
||||||
return AdminError{
|
return AdminError{
|
||||||
Code: AdminUpdateApplyFailure,
|
Code: AdminUpdateApplyFailure,
|
||||||
|
24
cmd/update_fips.go
Normal file
24
cmd/update_fips.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// +build fips
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MinIO Cloud Storage, (C) 2021 MinIO, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Newer official download info URLs appear earlier below.
|
||||||
|
minioReleaseInfoURL = minioReleaseURL + "minio.fips.sha256sum"
|
||||||
|
)
|
@ -301,19 +301,22 @@ func TestParseReleaseData(t *testing.T) {
|
|||||||
data string
|
data string
|
||||||
expectedResult time.Time
|
expectedResult time.Time
|
||||||
expectedSha256hex string
|
expectedSha256hex string
|
||||||
|
expectedReleaseInfo string
|
||||||
expectedErr bool
|
expectedErr bool
|
||||||
}{
|
}{
|
||||||
{"more than two fields", time.Time{}, "", true},
|
{"more than two fields", time.Time{}, "", "", true},
|
||||||
{"more than", time.Time{}, "", true},
|
{"more than", time.Time{}, "", "", true},
|
||||||
{"more than.two.fields", time.Time{}, "", true},
|
{"more than.two.fields", time.Time{}, "", "", true},
|
||||||
{"more minio.RELEASE.fields", time.Time{}, "", true},
|
{"more minio.RELEASE.fields", time.Time{}, "", "", true},
|
||||||
{"more minio.RELEASE.2016-10-07T01-16-39Z", time.Time{}, "", true},
|
{"more minio.RELEASE.2016-10-07T01-16-39Z", time.Time{}, "", "", true},
|
||||||
{"fbe246edbd382902db9a4035df7dce8cb441357d minio.RELEASE.2016-10-07T01-16-39Z\n", releaseTime, "fbe246edbd382902db9a4035df7dce8cb441357d", false},
|
{"fbe246edbd382902db9a4035df7dce8cb441357d minio.RELEASE.2016-10-07T01-16-39Z\n", releaseTime, "fbe246edbd382902db9a4035df7dce8cb441357d",
|
||||||
{"fbe246edbd382902db9a4035df7dce8cb441357d minio.RELEASE.2016-10-07T01-16-39Z.customer-hotfix\n", releaseTime, "fbe246edbd382902db9a4035df7dce8cb441357d", false},
|
"minio.RELEASE.2016-10-07T01-16-39Z", false},
|
||||||
|
{"fbe246edbd382902db9a4035df7dce8cb441357d minio.RELEASE.2016-10-07T01-16-39Z.customer-hotfix\n", releaseTime, "fbe246edbd382902db9a4035df7dce8cb441357d",
|
||||||
|
"minio.RELEASE.2016-10-07T01-16-39Z.customer-hotfix", false},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
sha256Sum, result, err := parseReleaseData(testCase.data)
|
sha256Sum, result, releaseInfo, err := parseReleaseData(testCase.data)
|
||||||
if !testCase.expectedErr {
|
if !testCase.expectedErr {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("error case %d: expected no error, got: %v", i+1, err)
|
t.Errorf("error case %d: expected no error, got: %v", i+1, err)
|
||||||
@ -328,6 +331,9 @@ func TestParseReleaseData(t *testing.T) {
|
|||||||
if !testCase.expectedResult.Equal(result) {
|
if !testCase.expectedResult.Equal(result) {
|
||||||
t.Errorf("case %d: result: expected: %v, got: %v", i+1, testCase.expectedResult, result)
|
t.Errorf("case %d: result: expected: %v, got: %v", i+1, testCase.expectedResult, result)
|
||||||
}
|
}
|
||||||
|
if testCase.expectedReleaseInfo != releaseInfo {
|
||||||
|
t.Errorf("case %d: result: expected: %v, got: %v", i+1, testCase.expectedReleaseInfo, releaseInfo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user