Commit 9c221719 authored by Jeromy's avatar Jeromy Committed by Juan Batiz-Benet

switch over to using a lock file for daemon connections

parent ac143045
......@@ -27,16 +27,17 @@ func catCmd(c *commander.Command, inp []string) error {
return nil
}
conf, err := getConfigDir(c.Parent)
if err != nil {
return err
}
com := daemon.NewCommand()
com.Command = "cat"
com.Args = inp
err := daemon.SendCommand(com, "localhost:12345")
err = daemon.SendCommand(com, conf)
if err != nil {
conf, err := getConfigDir(c.Parent)
if err != nil {
return err
}
n, err := localNode(conf, false)
if err != nil {
return err
......
......@@ -12,6 +12,8 @@ import (
u "github.com/jbenet/go-ipfs/util"
)
// CommanderFunc is a function that can be passed into the Commander library as
// a command handler. Defined here because commander lacks this definition.
type CommanderFunc func(*commander.Command, []string) error
// MakeCommand Wraps a commands.CmdFunc so that it may be safely run by the
......
......@@ -56,7 +56,7 @@ func mountCmd(c *commander.Command, inp []string) error {
return err
}
dl, err := daemon.NewDaemonListener(n, maddr)
dl, err := daemon.NewDaemonListener(n, maddr, conf)
if err != nil {
fmt.Println("Failed to create daemon listener.")
return err
......
......@@ -17,12 +17,25 @@ import (
// Error indicating the max depth has been exceded.
var ErrDepthLimitExceeded = fmt.Errorf("depth limit exceeded")
// Add is a command that imports files and directories -- given as arguments -- into ipfs.
func Add(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
depth := 1
// if recursive, set depth to reflect so
if r, ok := opts["r"].(bool); r && ok {
depth = -1
}
// add every path in args
for _, path := range args {
// get absolute path, as incoming arg may be relative
path, err := filepath.Abs(path)
if err != nil {
return fmt.Errorf("addFile error: %v", err)
}
// Add the file
nd, err := AddPath(n, path, depth)
if err != nil {
if err == ErrDepthLimitExceeded && depth == 1 {
......@@ -31,6 +44,7 @@ func Add(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Wr
return fmt.Errorf("addFile error: %v", err)
}
// get the key to print it
k, err := nd.Key()
if err != nil {
return fmt.Errorf("addFile error: %v", err)
......@@ -41,6 +55,7 @@ func Add(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Wr
return nil
}
// AddPath adds a particular path to ipfs.
func AddPath(n *core.IpfsNode, fpath string, depth int) (*dag.Node, error) {
if depth == 0 {
return nil, ErrDepthLimitExceeded
......
......@@ -3,21 +3,28 @@ package daemon
import (
"encoding/json"
"fmt"
"io"
"net"
"os"
core "github.com/jbenet/go-ipfs/core"
"github.com/jbenet/go-ipfs/core/commands"
u "github.com/jbenet/go-ipfs/util"
"github.com/op/go-logging"
"github.com/camlistore/lock"
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
)
var log = logging.MustGetLogger("daemon")
// DaemonListener listens to an initialized IPFS node and can send it commands instead of
// starting up a new set of connections
type DaemonListener struct {
node *core.IpfsNode
list net.Listener
closed bool
lk io.Closer
}
//Command accepts user input and can be sent to the running IPFS node
......@@ -27,21 +34,46 @@ type Command struct {
Opts map[string]interface{}
}
func NewDaemonListener(ipfsnode *core.IpfsNode, addr *ma.Multiaddr) (*DaemonListener, error) {
func NewDaemonListener(ipfsnode *core.IpfsNode, addr *ma.Multiaddr, confdir string) (*DaemonListener, error) {
var err error
confdir, err = u.TildeExpansion(confdir)
if err != nil {
return nil, err
}
lk, err := lock.Lock(confdir + "/daemon.lock")
if err != nil {
return nil, err
}
network, host, err := addr.DialArgs()
if err != nil {
return nil, err
}
ofi, err := os.Create(confdir + "/rpcaddress")
if err != nil {
log.Warning("Could not create rpcaddress file: %s", err)
return nil, err
}
_, err = ofi.Write([]byte(host))
if err != nil {
log.Warning("Could not write to rpcaddress file: %s", err)
return nil, err
}
ofi.Close()
list, err := net.Listen(network, host)
if err != nil {
return nil, err
}
fmt.Println("New daemon listener initialized.")
log.Info("New daemon listener initialized.")
return &DaemonListener{
node: ipfsnode,
list: list,
lk: lk,
}, nil
}
......@@ -60,6 +92,7 @@ func (dl *DaemonListener) Listen() {
if !dl.closed {
u.PErr("DaemonListener Accept: %v\n", err)
}
dl.lk.Close()
return
}
go dl.handleConnection(conn)
......
package daemon
import (
"bufio"
"encoding/json"
"errors"
"io"
"net"
"os"
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
u "github.com/jbenet/go-ipfs/util"
)
//SendCommand connects to the address on the network with a timeout and encodes the connection into JSON
func SendCommand(command *Command, server string) error {
// ErrDaemonNotRunning is returned when attempting to retrieve the daemon's
// address and the daemon is not actually running.
var ErrDaemonNotRunning = errors.New("daemon not running")
maddr, err := ma.NewMultiaddr(server)
func getDaemonAddr(confdir string) (string, error) {
var err error
confdir, err = u.TildeExpansion(confdir)
if err != nil {
return "", err
}
fi, err := os.Open(confdir + "/rpcaddress")
if err != nil {
log.Debug("getDaemonAddr failed: %s", err)
if err == os.ErrNotExist {
return "", ErrDaemonNotRunning
}
return "", err
}
read := bufio.NewReader(fi)
// TODO: operating system agostic line delim
line, err := read.ReadBytes('\n')
if err != nil && err != io.EOF {
return "", err
}
return string(line), nil
}
// SendCommand issues a command (of type daemon.Command) to the daemon, if it
// is running (if not, errors out). This is done over network RPC API. The
// address of the daemon is retrieved from the configuration directory, where
// live daemons write their addresses to special files.
func SendCommand(command *Command, confdir string) error {
server, err := getDaemonAddr(confdir)
if err != nil {
return err
}
network, host, err := maddr.DialArgs()
maddr, err := ma.NewMultiaddr(server)
if err != nil {
return err
}
network, host, err := maddr.DialArgs()
conn, err := net.Dial(network, host)
if err != nil {
return err
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment