agent/plugins/configurepackage/localpackages/localpackages_lock.go (39 lines of code) (raw):
// Copyright 2016 Amazon.com, Inc. or its affiliates. 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. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.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 localpackages
import (
"errors"
"fmt"
"sync"
"github.com/aws/amazon-ssm-agent/agent/fileutil/filelock"
)
const (
lockTimeoutInSeconds = 30 * 60 // 30 minutes
)
// Prevent multiple actions for the same package at the same time
var lockPackageAction = &sync.Mutex{}
var mapPackageAction = make(map[string]string)
// lockPackage adds the package name to the list of packages currently being acted on in a threadsafe way
func lockPackage(filelocker filelock.FileLocker, lockPath string, packageArn string, action string) error {
lockPackageAction.Lock()
defer lockPackageAction.Unlock()
if val, ok := mapPackageAction[packageArn]; ok {
return errors.New(fmt.Sprintf(`Package "%v" is already in the process of action "%v"`, packageArn, val))
}
ownerId := filelock.GetOwnerIdForProcess()
locked, err := filelocker.Lock(lockPath, ownerId, lockTimeoutInSeconds)
if err != nil {
return errors.New(fmt.Sprintf(`Error locking package "%v": "%v"`, packageArn, err))
}
if !locked {
return errors.New(fmt.Sprintf(`Package "%v" is already in the process of other action`, packageArn))
}
mapPackageAction[packageArn] = action
return nil
}
// unlockPackage removes the package name from the list of packages currently being acted on in a threadsafe way
func unlockPackage(filelocker filelock.FileLocker, lockPath string, packageArn string) error {
lockPackageAction.Lock()
defer lockPackageAction.Unlock()
if _, ok := mapPackageAction[packageArn]; ok {
delete(mapPackageAction, packageArn)
}
ownerId := filelock.GetOwnerIdForProcess()
_, err := filelocker.Unlock(lockPath, ownerId)
return err
}