github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/cmd/snap/cmd_prepare_image.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2014-2019 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 main 21 22 import ( 23 "os" 24 "strings" 25 26 "github.com/jessevdk/go-flags" 27 28 "github.com/snapcore/snapd/i18n" 29 "github.com/snapcore/snapd/image" 30 ) 31 32 type cmdPrepareImage struct { 33 Classic bool `long:"classic"` 34 Architecture string `long:"arch"` 35 36 Positional struct { 37 ModelAssertionFn string 38 TargetDir string 39 } `positional-args:"yes" required:"yes"` 40 41 Channel string `long:"channel"` 42 // TODO: introduce SnapWithChannel? 43 Snaps []string `long:"snap" value-name:"<snap>[=<channel>]"` 44 ExtraSnaps []string `long:"extra-snaps" hidden:"yes"` // DEPRECATED 45 } 46 47 func init() { 48 addCommand("prepare-image", 49 i18n.G("Prepare a device image"), 50 i18n.G(` 51 The prepare-image command performs some of the steps necessary for 52 creating device images. 53 54 For core images it is not invoked directly but usually via 55 ubuntu-image. 56 57 For preparing classic images it supports a --classic mode`), 58 func() flags.Commander { return &cmdPrepareImage{} }, 59 map[string]string{ 60 // TRANSLATORS: This should not start with a lowercase letter. 61 "classic": i18n.G("Enable classic mode to prepare a classic model image"), 62 // TRANSLATORS: This should not start with a lowercase letter. 63 "arch": i18n.G("Specify an architecture for snaps for --classic when the model does not"), 64 // TRANSLATORS: This should not start with a lowercase letter. 65 "snap": i18n.G("Include the given snap from the store or a local file and/or specify the channel to track for the given snap"), 66 // TRANSLATORS: This should not start with a lowercase letter. 67 "extra-snaps": i18n.G("Extra snaps to be installed (DEPRECATED)"), 68 // TRANSLATORS: This should not start with a lowercase letter. 69 "channel": i18n.G("The channel to use"), 70 }, []argDesc{ 71 { 72 // TRANSLATORS: This needs to begin with < and end with > 73 name: i18n.G("<model-assertion>"), 74 // TRANSLATORS: This should not start with a lowercase letter. 75 desc: i18n.G("The model assertion name"), 76 }, { 77 // TRANSLATORS: This needs to begin with < and end with > 78 name: i18n.G("<target-dir>"), 79 // TRANSLATORS: This should not start with a lowercase letter. 80 desc: i18n.G("The target directory"), 81 }, 82 }) 83 } 84 85 var imagePrepare = image.Prepare 86 87 func (x *cmdPrepareImage) Execute(args []string) error { 88 opts := &image.Options{ 89 Snaps: x.ExtraSnaps, 90 ModelFile: x.Positional.ModelAssertionFn, 91 Channel: x.Channel, 92 Architecture: x.Architecture, 93 } 94 95 snaps := make([]string, 0, len(x.Snaps)+len(x.ExtraSnaps)) 96 snapChannels := make(map[string]string) 97 for _, snapWChannel := range x.Snaps { 98 snapAndChannel := strings.SplitN(snapWChannel, "=", 2) 99 snaps = append(snaps, snapAndChannel[0]) 100 if len(snapAndChannel) == 2 { 101 snapChannels[snapAndChannel[0]] = snapAndChannel[1] 102 } 103 } 104 105 snaps = append(snaps, x.ExtraSnaps...) 106 107 if len(snaps) != 0 { 108 opts.Snaps = snaps 109 } 110 if len(snapChannels) != 0 { 111 opts.SnapChannels = snapChannels 112 } 113 114 // store-wide cohort key via env, see image/options.go 115 opts.WideCohortKey = os.Getenv("UBUNTU_STORE_COHORT_KEY") 116 117 opts.PrepareDir = x.Positional.TargetDir 118 opts.Classic = x.Classic 119 120 return imagePrepare(opts) 121 }