agentendpoint/patch_linux.go (98 lines of code) (raw):
// Copyright 2018 Google Inc. All Rights Reserved.
//
// 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 agentendpoint
import (
"context"
"errors"
"regexp"
"strings"
"time"
"github.com/GoogleCloudPlatform/osconfig/clog"
"github.com/GoogleCloudPlatform/osconfig/ospatch"
"github.com/GoogleCloudPlatform/osconfig/packages"
"github.com/GoogleCloudPlatform/osconfig/retryutil"
"cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb"
)
func (r *patchTask) runUpdates(ctx context.Context) error {
var errs []string
const retryPeriod = 3 * time.Minute
// Check for both apt-get and dpkg-query to give us a clean signal.
if packages.AptExists && packages.DpkgQueryExists {
excludes, err := convertInputToExcludes(r.Task.GetPatchConfig().GetApt().GetExcludes())
if err != nil {
return err
}
opts := []ospatch.AptGetUpgradeOption{
ospatch.AptGetDryRun(r.Task.GetDryRun()),
ospatch.AptGetExcludes(excludes),
ospatch.AptGetExclusivePackages(r.Task.GetPatchConfig().GetApt().GetExclusivePackages()),
}
switch r.Task.GetPatchConfig().GetApt().GetType() {
case agentendpointpb.AptSettings_DIST:
opts = append(opts, ospatch.AptGetUpgradeType(packages.AptGetDistUpgrade))
}
clog.Debugf(ctx, "Installing APT package updates.")
if err := retryutil.RetryFunc(ctx, retryPeriod, "installing APT package updates", func() error { return ospatch.RunAptGetUpgrade(ctx, opts...) }); err != nil {
errs = append(errs, err.Error())
}
}
if packages.YumExists && packages.RPMQueryExists {
excludes, err := convertInputToExcludes(r.Task.GetPatchConfig().GetYum().GetExcludes())
if err != nil {
return err
}
opts := []ospatch.YumUpdateOption{
ospatch.YumUpdateSecurity(r.Task.GetPatchConfig().GetYum().GetSecurity()),
ospatch.YumUpdateMinimal(r.Task.GetPatchConfig().GetYum().GetMinimal()),
ospatch.YumUpdateExcludes(excludes),
ospatch.YumExclusivePackages(r.Task.GetPatchConfig().GetYum().GetExclusivePackages()),
ospatch.YumDryRun(r.Task.GetDryRun()),
}
clog.Debugf(ctx, "Installing YUM package updates.")
if err := retryutil.RetryFunc(ctx, retryPeriod, "installing YUM package updates", func() error { return ospatch.RunYumUpdate(ctx, opts...) }); err != nil {
errs = append(errs, err.Error())
}
}
if packages.ZypperExists && packages.RPMQueryExists {
excludes, err := convertInputToExcludes(r.Task.GetPatchConfig().GetZypper().GetExcludes())
if err != nil {
return err
}
opts := []ospatch.ZypperPatchOption{
ospatch.ZypperPatchCategories(r.Task.GetPatchConfig().GetZypper().GetCategories()),
ospatch.ZypperPatchSeverities(r.Task.GetPatchConfig().GetZypper().GetSeverities()),
ospatch.ZypperUpdateWithUpdate(r.Task.GetPatchConfig().GetZypper().GetWithUpdate()),
ospatch.ZypperUpdateWithOptional(r.Task.GetPatchConfig().GetZypper().GetWithOptional()),
ospatch.ZypperUpdateWithExcludes(excludes),
ospatch.ZypperUpdateWithExclusivePatches(r.Task.GetPatchConfig().GetZypper().GetExclusivePatches()),
ospatch.ZypperUpdateDryrun(r.Task.GetDryRun()),
}
clog.Debugf(ctx, "Installing Zypper updates.")
if err := retryutil.RetryFunc(ctx, retryPeriod, "installing Zypper updates", func() error { return ospatch.RunZypperPatch(ctx, opts...) }); err != nil {
errs = append(errs, err.Error())
}
}
if errs == nil {
return nil
}
return errors.New(strings.Join(errs, ",\n"))
}
func convertInputToExcludes(input []string) ([]*ospatch.Exclude, error) {
var output []*ospatch.Exclude
for _, s := range input {
if len(s) >= 2 && (s)[0] == '/' && s[len(s)-1] == '/' {
exclude, err := regexExcludeFromString(s[1 : len(s)-1])
if err != nil {
return nil, err
}
output = append(output, exclude)
} else {
output = append(output, ospatch.CreateStringExclude(&s))
}
}
return output, nil
}
func regexExcludeFromString(s string) (*ospatch.Exclude, error) {
compile, err := regexp.Compile(s)
if err != nil {
return nil, err
}
return ospatch.CreateRegexExclude(compile), nil
}