github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/scripts/juju-force-upgrade/main.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package main
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"path/filepath"
    10  
    11  	"github.com/juju/clock"
    12  	"github.com/juju/errors"
    13  	"github.com/juju/gnuflag"
    14  	"github.com/juju/loggo"
    15  	"github.com/juju/version"
    16  	"gopkg.in/juju/names.v2"
    17  
    18  	"github.com/juju/juju/agent"
    19  	"github.com/juju/juju/mongo"
    20  	"github.com/juju/juju/state"
    21  	jversion "github.com/juju/juju/version"
    22  )
    23  
    24  var logger = loggo.GetLogger("juju.forceupgrade")
    25  
    26  func checkErr(label string, err error) {
    27  	if err != nil {
    28  		logger.Errorf("%s: %s", label, err)
    29  		os.Exit(1)
    30  	}
    31  }
    32  
    33  const dataDir = "/var/lib/juju"
    34  
    35  func getState() (*state.StatePool, error) {
    36  	tag, err := getCurrentMachineTag(dataDir)
    37  	if err != nil {
    38  		return nil, errors.Annotate(err, "finding machine tag")
    39  	}
    40  
    41  	logger.Infof("current machine tag: %s", tag)
    42  
    43  	config, err := getConfig(tag)
    44  	if err != nil {
    45  		return nil, errors.Annotate(err, "loading agent config")
    46  	}
    47  
    48  	mongoInfo, available := config.MongoInfo()
    49  	if !available {
    50  		return nil, errors.New("mongo info not available from agent config")
    51  	}
    52  	session, err := mongo.DialWithInfo(*mongoInfo, mongo.DefaultDialOpts())
    53  	if err != nil {
    54  		return nil, errors.Trace(err)
    55  	}
    56  	defer session.Close()
    57  
    58  	pool, err := state.OpenStatePool(state.OpenParams{
    59  		Clock:              clock.WallClock,
    60  		ControllerTag:      config.Controller(),
    61  		ControllerModelTag: config.Model(),
    62  		MongoSession:       session,
    63  	})
    64  	if err != nil {
    65  		return nil, errors.Annotate(err, "opening state connection")
    66  	}
    67  	return pool, nil
    68  }
    69  
    70  func getCurrentMachineTag(datadir string) (names.MachineTag, error) {
    71  	var empty names.MachineTag
    72  	values, err := filepath.Glob(filepath.Join(datadir, "agents", "machine-*"))
    73  	if err != nil {
    74  		return empty, errors.Annotate(err, "problem globbing")
    75  	}
    76  	switch len(values) {
    77  	case 0:
    78  		return empty, errors.Errorf("no machines found")
    79  	case 1:
    80  		return names.ParseMachineTag(filepath.Base(values[0]))
    81  	default:
    82  		return empty, errors.Errorf("too many options: %v", values)
    83  	}
    84  }
    85  
    86  func getConfig(tag names.MachineTag) (agent.ConfigSetterWriter, error) {
    87  	path := agent.ConfigPath("/var/lib/juju", tag)
    88  	return agent.ReadConfig(path)
    89  }
    90  
    91  func main() {
    92  	loggo.GetLogger("").SetLogLevel(loggo.TRACE)
    93  	gnuflag.Usage = func() {
    94  		fmt.Printf("Usage: %s <model-uuid> <version>\n", os.Args[0])
    95  		os.Exit(1)
    96  	}
    97  
    98  	gnuflag.Parse(true)
    99  
   100  	args := gnuflag.Args()
   101  	if len(args) < 2 {
   102  		gnuflag.Usage()
   103  	}
   104  
   105  	modelUUID := args[0]
   106  	agentVersion := version.MustParse(args[1])
   107  	if agentVersion.Compare(jversion.Current) < 0 {
   108  		// Force the client to think it is at least as new as the desired version
   109  		jversion.Current = agentVersion
   110  	}
   111  
   112  	statePool, err := getState()
   113  	checkErr("getting state connection", err)
   114  	defer statePool.Close()
   115  
   116  	modelSt, err := statePool.Get(modelUUID)
   117  	checkErr("open model", err)
   118  	defer func() {
   119  		modelSt.Release()
   120  		statePool.Remove(modelUUID)
   121  	}()
   122  
   123  	checkErr("set model agent version", modelSt.SetModelAgentVersion(agentVersion, true))
   124  }