github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/seed/helpers.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2016-2020 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package seed
    21  
    22  import (
    23  	"fmt"
    24  	"io/ioutil"
    25  	"os"
    26  	"path/filepath"
    27  
    28  	"github.com/snapcore/snapd/asserts"
    29  	"github.com/snapcore/snapd/asserts/sysdb"
    30  	"github.com/snapcore/snapd/snap"
    31  	"github.com/snapcore/snapd/snap/snapfile"
    32  )
    33  
    34  var trusted = sysdb.Trusted()
    35  
    36  func MockTrusted(mockTrusted []asserts.Assertion) (restore func()) {
    37  	prevTrusted := trusted
    38  	trusted = mockTrusted
    39  	return func() {
    40  		trusted = prevTrusted
    41  	}
    42  }
    43  
    44  func newMemAssertionsDB() (db asserts.RODatabase, commitTo func(*asserts.Batch) error, err error) {
    45  	memDB, err := asserts.OpenDatabase(&asserts.DatabaseConfig{
    46  		Backstore: asserts.NewMemoryBackstore(),
    47  		Trusted:   trusted,
    48  	})
    49  	if err != nil {
    50  		return nil, nil, err
    51  	}
    52  
    53  	commitTo = func(b *asserts.Batch) error {
    54  		return b.CommitTo(memDB, nil)
    55  	}
    56  
    57  	return memDB, commitTo, nil
    58  }
    59  
    60  func loadAssertions(assertsDir string, loadedFunc func(*asserts.Ref) error) (*asserts.Batch, error) {
    61  	dc, err := ioutil.ReadDir(assertsDir)
    62  	if err != nil {
    63  		if os.IsNotExist(err) {
    64  			return nil, ErrNoAssertions
    65  		}
    66  		return nil, fmt.Errorf("cannot read assertions dir: %s", err)
    67  	}
    68  
    69  	batch := asserts.NewBatch(nil)
    70  	for _, fi := range dc {
    71  		fn := filepath.Join(assertsDir, fi.Name())
    72  		refs, err := readAsserts(batch, fn)
    73  		if err != nil {
    74  			return nil, fmt.Errorf("cannot read assertions: %s", err)
    75  		}
    76  		if loadedFunc != nil {
    77  			for _, ref := range refs {
    78  				if err := loadedFunc(ref); err != nil {
    79  					return nil, err
    80  				}
    81  			}
    82  		}
    83  	}
    84  
    85  	return batch, nil
    86  }
    87  
    88  func readAsserts(batch *asserts.Batch, fn string) ([]*asserts.Ref, error) {
    89  	f, err := os.Open(fn)
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  	defer f.Close()
    94  	return batch.AddStream(f)
    95  }
    96  
    97  func readInfo(snapPath string, si *snap.SideInfo) (*snap.Info, error) {
    98  	snapf, err := snapfile.Open(snapPath)
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  	return snap.ReadInfoFromSnapFile(snapf, si)
   103  }
   104  
   105  func snapTypeFromModel(modSnap *asserts.ModelSnap) snap.Type {
   106  	switch modSnap.SnapType {
   107  	case "base":
   108  		return snap.TypeBase
   109  	case "core":
   110  		return snap.TypeOS
   111  	case "gadget":
   112  		return snap.TypeGadget
   113  	case "kernel":
   114  		return snap.TypeKernel
   115  	case "snapd":
   116  		return snap.TypeSnapd
   117  	default:
   118  		return snap.TypeApp
   119  	}
   120  }
   121  
   122  func essentialSnapTypesToModelFilter(essentialTypes []snap.Type) func(modSnap *asserts.ModelSnap) bool {
   123  	m := make(map[string]bool, len(essentialTypes))
   124  	for _, t := range essentialTypes {
   125  		switch t {
   126  		case snap.TypeBase:
   127  			m["base"] = true
   128  		case snap.TypeOS:
   129  			m["core"] = true
   130  		case snap.TypeGadget:
   131  			m["gadget"] = true
   132  		case snap.TypeKernel:
   133  			m["kernel"] = true
   134  		case snap.TypeSnapd:
   135  			m["snapd"] = true
   136  		}
   137  	}
   138  
   139  	return func(modSnap *asserts.ModelSnap) bool {
   140  		return m[modSnap.SnapType]
   141  	}
   142  }
   143  
   144  func findBrand(seed Seed, db asserts.RODatabase) (*asserts.Account, error) {
   145  	a, err := db.Find(asserts.AccountType, map[string]string{
   146  		"account-id": seed.Model().BrandID(),
   147  	})
   148  	if err != nil {
   149  		return nil, fmt.Errorf("internal error: %v", err)
   150  	}
   151  	return a.(*asserts.Account), nil
   152  }