Skip to content

Commit

Permalink
Merge pull request mendersoftware#519 from mendersoftware/artifact-de…
Browse files Browse the repository at this point in the history
…pends-i4

MEN-3345: Merge Artifact depends i4
  • Loading branch information
Kristian Amlie authored Apr 14, 2020
2 parents da6e27a + c2b0941 commit 912f96f
Show file tree
Hide file tree
Showing 42 changed files with 595 additions and 203 deletions.
2 changes: 1 addition & 1 deletion LIC_FILES_CHKSUM.sha256
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Apache-2.0 license.
32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99 LICENSE
beb140be4cd64599bedc691a55b2729c9cc611a4b9d6ec44e01270105daf18a2 vendor/github.com/mendersoftware/mendertesting/LICENSE
beb140be4cd64599bedc691a55b2729c9cc611a4b9d6ec44e01270105daf18a2 vendor/github.com/mendersoftware/mender-artifact/LICENSE
32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99 vendor/github.com/mendersoftware/mender-artifact/LICENSE
#
# BSD 2 Clause license.
8d427fd87bc9579ea368fde3d49f9ca22eac857f91a9dec7e3004bdfab7dee86 vendor/github.com/pkg/errors/LICENSE
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ V ?=
PKGS = $(shell go list ./... | grep -v vendor)
PKGFILES = $(shell find . \( -path ./vendor -o -path ./Godeps \) -prune \
-o -type f -name '*.go' -print)
PKGFILES_notest = $(shell echo $(PKGFILES) | tr ' ' '\n' | grep -v _test.go)
PKGFILES_notest = $(shell echo $(PKGFILES) | tr ' ' '\n' | grep -v '\(client/test\|_test.go\)' )
GOCYCLO ?= 15

CGO_ENABLED=1
Expand Down
86 changes: 50 additions & 36 deletions app/mender.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
inv "github.com/mendersoftware/mender/inventory"
"github.com/mendersoftware/mender/statescript"
"github.com/mendersoftware/mender/store"
"github.com/mendersoftware/mender/utils"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -86,6 +87,10 @@ var (
}
)

const (
errMsgInvalidDependsTypeF = "invalid type %T for dependency with name %s"
)

func StateStatus(m datastore.MenderState) string {
status, ok := stateStatus[m]
if ok {
Expand Down Expand Up @@ -275,45 +280,43 @@ func (m *Mender) FetchUpdate(url string) (io.ReadCloser, int64, error) {
return m.updater.FetchUpdate(m.api, url, m.GetRetryPollInterval())
}

func verifyArtifactDependencies(depends, provides map[string]interface{}) error {
// Generic closure for checking if element is present in slice.
elemInSlice := func(elem string, slice []string) bool {
for _, s := range slice {
if s == elem {
return true
}
}
return false
}
func verifyArtifactDependencies(
depends map[string]interface{},
provides map[string]string,
) error {

for key, depend := range depends {
if key == "compatible_devices" {
if key == "device_type" {
// handled elsewhere
continue
}
switch depend := depend.(type) {
case []string:
if len(depend) == 0 {
continue
}
case string:
if depend == "" {
continue
}
default:
return errors.Errorf(
"Invalid type for dependency with name %s", key)
}
if p, ok := provides[key]; ok {
switch depend.(type) {
case []interface{}:
if ok, err := utils.ElemInSlice(depend, p); ok {
continue
} else if err == utils.ErrInvalidType {
return errors.Errorf(
errMsgInvalidDependsTypeF,
depend,
key,
)
}
case []string:
if elemInSlice(p.(string), depend.([]string)) {
// No need to check type here - all deterministic
if ok, _ := utils.ElemInSlice(depend, p); ok {
continue
}
case string:
if p == depend {
if p == depend.(string) {
continue
}
default:
return errors.Errorf(
errMsgInvalidDependsTypeF,
depend,
key,
)
}
return errors.Errorf(errMsgDependencyNotSatisfiedF,
key, depend, provides[key])
Expand All @@ -324,27 +327,38 @@ func verifyArtifactDependencies(depends, provides map[string]interface{}) error
return nil
}

// Check if new update is available. In case of errors, returns nil and error
// that occurred. If no update is available *UpdateInfo is nil, otherwise it
// contains update information.
// CheckUpdate Check if new update is available. In case of errors, returns nil
// and error that occurred. If no update is available *UpdateInfo is nil,
// otherwise it contains update information.
func (m *Mender) CheckUpdate() (*datastore.UpdateInfo, menderError) {
currentArtifactName, err := m.GetCurrentArtifactName()
if err != nil || currentArtifactName == "" {
log.Error("could not get the current artifact name")
log.Error("could not get the current Artifact name")
if err == nil {
err = errors.New("artifact name is empty")
}
return nil, NewTransientError(fmt.Errorf("could not read the artifact name. This is a necessary condition in order for a mender update to finish safely. Please give the current artifact a name (This can be done by adding a name to the file /etc/mender/artifact_info) err: %v", err))
return nil, NewTransientError(fmt.Errorf("could not read the Artifact name. This is a necessary condition in order for a Mender update to finish safely. Please give the current Artifact a name (This can be done by adding a name to the file /etc/mender/artifact_info) err: %v", err))
}

deviceType, err := m.GetDeviceType()
if err != nil {
log.Errorf("Unable to verify the existing hardware. Update will continue anyways: %v : %v", m.Config.DeviceTypeFile, err)
log.Errorf("Unable to verify the existing hardware. Update will continue anyways: %v : %v",
m.Config.DeviceTypeFile, err)
}
haveUpdate, err := m.updater.GetScheduledUpdate(m.api.Request(m.authToken, nextServerIterator(m), reauthorize(m)),
m.Config.Servers[0].ServerURL, client.CurrentUpdate{
provides, err := m.DeviceManager.GetProvides()
if err != nil {
log.Errorf("Failed to load the device provides parameters from the datastore. Error: %v. Continuing...",
err)
}
haveUpdate, err := m.updater.GetScheduledUpdate(
m.api.Request(m.authToken,
nextServerIterator(m),
reauthorize(m)),
m.Config.Servers[0].ServerURL,
&client.CurrentUpdate{
Artifact: currentArtifactName,
DeviceType: deviceType,
Provides: provides,
})

if err != nil {
Expand Down Expand Up @@ -640,9 +654,9 @@ func (m *Mender) InventoryRefresh() error {
artifactName, err := m.GetCurrentArtifactName()
if err != nil || artifactName == "" {
if err == nil {
err = errors.New("artifact name is empty")
err = errors.New("Artifact name is empty")
}
errstr := fmt.Sprintf("could not read the artifact name. This is a necessary condition in order for a mender update to finish safely. Please give the current artifact a name (This can be done by adding a name to the file /etc/mender/artifact_info) err: %v", err)
errstr := fmt.Sprintf("could not read the artifact name. This is a necessary condition in order for a Mender update to finish safely. Please give the current Artifact a name (This can be done by adding a name to the file /etc/mender/artifact_info) err: %v", err)
return errors.Wrap(errNoArtifactName, errstr)
}

Expand Down
13 changes: 7 additions & 6 deletions app/mender_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ func Test_CheckUpdateSimple(t *testing.T) {
mender.ArtifactInfoFile = artifactInfo
mender.DeviceTypeFile = deviceType

srv.Update.Current = client.CurrentUpdate{
srv.Update.Current = &client.CurrentUpdate{
Artifact: "fake-id",
DeviceType: "hammer",
}
Expand Down Expand Up @@ -308,8 +308,9 @@ func Test_CheckUpdateSimple(t *testing.T) {
srv.Update.Has = true
up, err = mender.CheckUpdate()
assert.NoError(t, err)
assert.NotNil(t, up)
assert.Equal(t, *up, srv.Update.Data)
if assert.NotNil(t, up) {
assert.Equal(t, *up, srv.Update.Data)
}

// pretend that we got 204 No Content from the server, i.e empty response body
srv.Update.Has = false
Expand Down Expand Up @@ -629,7 +630,7 @@ func TestAuthToken(t *testing.T) {
assert.Equal(t, []byte("tokendata"), token)

ts.Update.Unauthorized = true
ts.Update.Current = client.CurrentUpdate{
ts.Update.Current = &client.CurrentUpdate{
Artifact: "fake-id",
DeviceType: "foo-bar",
}
Expand Down Expand Up @@ -1005,7 +1006,7 @@ func TestReauthorization(t *testing.T) {
srv.Auth.Token = []byte(`foo`)
srv.Auth.Authorize = true
srv.Auth.Verify = true
srv.Update.Current = client.CurrentUpdate{
srv.Update.Current = &client.CurrentUpdate{
Artifact: "mender-image",
DeviceType: "dev",
}
Expand Down Expand Up @@ -1065,7 +1066,7 @@ func TestFailoverServers(t *testing.T) {
defer srv1.Close()
defer srv2.Close()
// Give srv2 knowledge about client artifact- and device name
srv2.Update.Current = client.CurrentUpdate{
srv2.Update.Current = &client.CurrentUpdate{
Artifact: "mender-image",
DeviceType: "dev",
}
Expand Down
4 changes: 2 additions & 2 deletions app/standalone.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import (
type standaloneData struct {
artifactName string
artifactGroup string
artifactTypeInfoProvides map[string]interface{}
artifactTypeInfoProvides map[string]string
installers []installer.PayloadUpdatePerformer
}

Expand Down Expand Up @@ -134,7 +134,7 @@ func doStandaloneInstallStatesDownload(art io.ReadCloser, key []byte,
}
if grp, ok := standaloneData.
artifactTypeInfoProvides["artifact_group"]; ok {
standaloneData.artifactGroup = grp.(string)
standaloneData.artifactGroup = grp
delete(standaloneData.artifactTypeInfoProvides,
"artifact_group")
}
Expand Down
4 changes: 2 additions & 2 deletions app/standalone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func TestDoManualUpdateArtifactV3Dependencies(t *testing.T) {
ArtifactGroup: []string{"testGroup"},
CompatibleDevices: []string{"qemux86-64"},
}
typeInfoDepends := &map[string]interface{}{
typeInfoDepends := map[string]interface{}{
"testKey": "testValue",
}

Expand Down Expand Up @@ -1039,7 +1039,7 @@ func TestStandaloneStoreAndRestore(t *testing.T) {
sd: &standaloneData{
artifactName: "foobar",
artifactGroup: "baz",
artifactTypeInfoProvides: map[string]interface{}{
artifactTypeInfoProvides: map[string]string{
"bugs": "bunny",
"daffy": "duck",
},
Expand Down
6 changes: 3 additions & 3 deletions app/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -853,9 +853,9 @@ func (u *updateStoreState) maybeVerifyArtifactDependsAndProvides(
log.Error("Failed to extract artifact dependencies from " +
"header: " + err.Error())
} else if depends != nil {
var provides map[string]interface{}
var provides map[string]string
// load header-info provides
provides, err = datastore.LoadProvides(ctx.Store)
provides, err := datastore.LoadProvides(ctx.Store)
if err != nil {
log.Error(err.Error())
return err
Expand All @@ -880,7 +880,7 @@ func (u *updateStoreState) maybeVerifyArtifactDependsAndProvides(
}
delete(provides, "artifact_name")
if grp, ok := provides["artifact_group"]; ok {
u.update.Artifact.ArtifactGroup = grp.(string)
u.update.Artifact.ArtifactGroup = grp
// remove duplication
delete(provides, "artifact_group")
}
Expand Down
8 changes: 4 additions & 4 deletions app/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ func TestStateUpdateCommit(t *testing.T) {
defer os.RemoveAll(tempDir)
DeploymentLogger = NewDeploymentLogManager(tempDir)

artifactTypeInfoProvides := map[string]interface{}{
artifactTypeInfoProvides := map[string]string{
"test-kwrd": "test-value",
}

Expand Down Expand Up @@ -471,7 +471,7 @@ func TestStateUpdateCommit(t *testing.T) {
assert.Equal(t, artifactGroup, "TestGroup")
storeBuf, err = ms.ReadAll(datastore.ArtifactTypeInfoProvidesKey)
assert.NoError(t, err)
var typeProvides map[string]interface{}
var typeProvides map[string]string
err = json.Unmarshal(storeBuf, &typeProvides)
assert.NoError(t, err)
assert.Equal(t, typeProvides, artifactTypeInfoProvides)
Expand Down Expand Up @@ -789,12 +789,12 @@ func TestStateUpdateStore(t *testing.T) {
ArtifactGroup: []string{"TestGroup"},
CompatibleDevices: []string{"vexpress-qemu"},
}
artifactTypeInfoProvides := map[string]interface{}{
artifactTypeInfoProvides := map[string]string{
"test": "moar-test",
}

stream, err := tests.CreateTestArtifactV3("test", "gzip",
artifactProvides, artifactDepends, &artifactTypeInfoProvides, nil)
artifactProvides, artifactDepends, artifactTypeInfoProvides, nil)
require.NoError(t, err)

update := &datastore.UpdateInfo{
Expand Down
Loading

0 comments on commit 912f96f

Please sign in to comment.