github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/core/commands/update.go (about)

     1  package commands
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  
     9  	cmds "github.com/ipfs/go-ipfs/commands"
    10  	"github.com/ipfs/go-ipfs/core"
    11  	"github.com/ipfs/go-ipfs/updates"
    12  )
    13  
    14  type UpdateOutput struct {
    15  	OldVersion string
    16  	NewVersion string
    17  }
    18  
    19  var UpdateCmd = &cmds.Command{
    20  	Helptext: cmds.HelpText{
    21  		Tagline: "Downloads and installs updates for IPFS (disabled)",
    22  		ShortDescription: `ipfs update is disabled until we can deploy the binaries to you over ipfs itself.
    23  
    24  		please use 'go get -u github.com/ipfs/go-ipfs/cmd/ipfs' until then.`,
    25  	},
    26  }
    27  
    28  // TODO: unexported until we can deploy the binaries over ipfs
    29  var updateCmd = &cmds.Command{
    30  	Helptext: cmds.HelpText{
    31  		Tagline:          "Downloads and installs updates for IPFS",
    32  		ShortDescription: "ipfs update is a utility command used to check for updates and apply them.",
    33  	},
    34  
    35  	Run: func(req cmds.Request, res cmds.Response) {
    36  		n, err := req.InvocContext().GetNode()
    37  		if err != nil {
    38  			res.SetError(err, cmds.ErrNormal)
    39  			return
    40  		}
    41  
    42  		output, err := updateApply(n)
    43  		if err != nil {
    44  			res.SetError(err, cmds.ErrNormal)
    45  			return
    46  		}
    47  		res.SetOutput(output)
    48  	},
    49  	Type: UpdateOutput{},
    50  	Subcommands: map[string]*cmds.Command{
    51  		"check": UpdateCheckCmd,
    52  		"log":   UpdateLogCmd,
    53  	},
    54  	Marshalers: cmds.MarshalerMap{
    55  		cmds.Text: func(res cmds.Response) (io.Reader, error) {
    56  			v := res.Output().(*UpdateOutput)
    57  			buf := new(bytes.Buffer)
    58  			if v.NewVersion != v.OldVersion {
    59  				buf.WriteString(fmt.Sprintf("Successfully updated to IPFS version '%s' (from '%s')\n",
    60  					v.NewVersion, v.OldVersion))
    61  			} else {
    62  				buf.WriteString(fmt.Sprintf("Already updated to latest version ('%s')\n", v.NewVersion))
    63  			}
    64  			return buf, nil
    65  		},
    66  	},
    67  }
    68  
    69  var UpdateCheckCmd = &cmds.Command{
    70  	Helptext: cmds.HelpText{
    71  		Tagline:          "Checks if updates are available",
    72  		ShortDescription: "'ipfs update check' checks if any updates are available for IPFS.\nNothing will be downloaded or installed.",
    73  	},
    74  
    75  	Run: func(req cmds.Request, res cmds.Response) {
    76  		n, err := req.InvocContext().GetNode()
    77  		if err != nil {
    78  			res.SetError(err, cmds.ErrNormal)
    79  			return
    80  		}
    81  
    82  		output, err := updateCheck(n)
    83  		if err != nil {
    84  			res.SetError(err, cmds.ErrNormal)
    85  			return
    86  		}
    87  		res.SetOutput(output)
    88  	},
    89  	Type: UpdateOutput{},
    90  	Marshalers: cmds.MarshalerMap{
    91  		cmds.Text: func(res cmds.Response) (io.Reader, error) {
    92  			v := res.Output().(*UpdateOutput)
    93  			buf := new(bytes.Buffer)
    94  			if v.NewVersion != v.OldVersion {
    95  				buf.WriteString(fmt.Sprintf("A new version of IPFS is available ('%s', currently running '%s')\n",
    96  					v.NewVersion, v.OldVersion))
    97  			} else {
    98  				buf.WriteString(fmt.Sprintf("Already updated to latest version ('%s')\n", v.NewVersion))
    99  			}
   100  			return buf, nil
   101  		},
   102  	},
   103  }
   104  
   105  var UpdateLogCmd = &cmds.Command{
   106  	Helptext: cmds.HelpText{
   107  		Tagline:          "List the changelog for the latest versions of IPFS",
   108  		ShortDescription: "This command is not yet implemented.",
   109  	},
   110  
   111  	Run: func(req cmds.Request, res cmds.Response) {
   112  		n, err := req.InvocContext().GetNode()
   113  		if err != nil {
   114  			res.SetError(err, cmds.ErrNormal)
   115  			return
   116  		}
   117  
   118  		output, err := updateLog(n)
   119  		if err != nil {
   120  			res.SetError(err, cmds.ErrNormal)
   121  			return
   122  		}
   123  		res.SetOutput(output)
   124  	},
   125  }
   126  
   127  // updateApply applies an update of the ipfs binary and shuts down the node if successful
   128  func updateApply(n *core.IpfsNode) (*UpdateOutput, error) {
   129  	// TODO: 'force bool' param that stops the daemon (if running) before update
   130  
   131  	output := &UpdateOutput{
   132  		OldVersion: updates.Version,
   133  	}
   134  
   135  	u, err := updates.CheckForUpdate()
   136  	if err != nil {
   137  		return nil, err
   138  	}
   139  
   140  	if u == nil {
   141  		output.NewVersion = updates.Version
   142  		return output, nil
   143  	}
   144  
   145  	output.NewVersion = u.Version
   146  
   147  	if n.OnlineMode() {
   148  		return nil, errors.New(`You must stop the IPFS daemon before updating.`)
   149  	}
   150  
   151  	if err = updates.Apply(u); err != nil {
   152  		return nil, err
   153  	}
   154  
   155  	return output, nil
   156  }
   157  
   158  // updateCheck checks wether there is an update available
   159  func updateCheck(n *core.IpfsNode) (*UpdateOutput, error) {
   160  	output := &UpdateOutput{
   161  		OldVersion: updates.Version,
   162  	}
   163  
   164  	u, err := updates.CheckForUpdate()
   165  	if err != nil {
   166  		return nil, err
   167  	}
   168  
   169  	if u == nil {
   170  		output.NewVersion = updates.Version
   171  		return output, nil
   172  	}
   173  
   174  	output.NewVersion = u.Version
   175  	return output, nil
   176  }
   177  
   178  // updateLog lists the version available online
   179  func updateLog(n *core.IpfsNode) (interface{}, error) {
   180  	// TODO
   181  	return nil, errors.New("Not yet implemented")
   182  }