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  }