github.com/ryanslade/nomad@v0.2.4-0.20160128061903-fc95782f2089/nomad/alloc_endpoint.go (about)

     1  package nomad
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/armon/go-metrics"
     7  	"github.com/hashicorp/go-memdb"
     8  	"github.com/hashicorp/nomad/nomad/structs"
     9  	"github.com/hashicorp/nomad/nomad/watch"
    10  )
    11  
    12  // Alloc endpoint is used for manipulating allocations
    13  type Alloc struct {
    14  	srv *Server
    15  }
    16  
    17  // List is used to list the allocations in the system
    18  func (a *Alloc) List(args *structs.AllocListRequest, reply *structs.AllocListResponse) error {
    19  	if done, err := a.srv.forward("Alloc.List", args, args, reply); done {
    20  		return err
    21  	}
    22  	defer metrics.MeasureSince([]string{"nomad", "alloc", "list"}, time.Now())
    23  
    24  	// Setup the blocking query
    25  	opts := blockingOptions{
    26  		queryOpts: &args.QueryOptions,
    27  		queryMeta: &reply.QueryMeta,
    28  		watch:     watch.NewItems(watch.Item{Table: "allocs"}),
    29  		run: func() error {
    30  			// Capture all the allocations
    31  			snap, err := a.srv.fsm.State().Snapshot()
    32  			if err != nil {
    33  				return err
    34  			}
    35  			var iter memdb.ResultIterator
    36  			if prefix := args.QueryOptions.Prefix; prefix != "" {
    37  				iter, err = snap.AllocsByIDPrefix(prefix)
    38  			} else {
    39  				iter, err = snap.Allocs()
    40  			}
    41  			if err != nil {
    42  				return err
    43  			}
    44  
    45  			var allocs []*structs.AllocListStub
    46  			for {
    47  				raw := iter.Next()
    48  				if raw == nil {
    49  					break
    50  				}
    51  				alloc := raw.(*structs.Allocation)
    52  				allocs = append(allocs, alloc.Stub())
    53  			}
    54  			reply.Allocations = allocs
    55  
    56  			// Use the last index that affected the jobs table
    57  			index, err := snap.Index("allocs")
    58  			if err != nil {
    59  				return err
    60  			}
    61  			reply.Index = index
    62  
    63  			// Set the query response
    64  			a.srv.setQueryMeta(&reply.QueryMeta)
    65  			return nil
    66  		}}
    67  	return a.srv.blockingRPC(&opts)
    68  }
    69  
    70  // GetAlloc is used to lookup a particular allocation
    71  func (a *Alloc) GetAlloc(args *structs.AllocSpecificRequest,
    72  	reply *structs.SingleAllocResponse) error {
    73  	if done, err := a.srv.forward("Alloc.GetAlloc", args, args, reply); done {
    74  		return err
    75  	}
    76  	defer metrics.MeasureSince([]string{"nomad", "alloc", "get_alloc"}, time.Now())
    77  
    78  	// Setup the blocking query
    79  	opts := blockingOptions{
    80  		queryOpts: &args.QueryOptions,
    81  		queryMeta: &reply.QueryMeta,
    82  		watch:     watch.NewItems(watch.Item{Alloc: args.AllocID}),
    83  		run: func() error {
    84  			// Lookup the allocation
    85  			snap, err := a.srv.fsm.State().Snapshot()
    86  			if err != nil {
    87  				return err
    88  			}
    89  			out, err := snap.AllocByID(args.AllocID)
    90  			if err != nil {
    91  				return err
    92  			}
    93  
    94  			// Setup the output
    95  			reply.Alloc = out
    96  			if out != nil {
    97  				reply.Index = out.ModifyIndex
    98  			} else {
    99  				// Use the last index that affected the nodes table
   100  				index, err := snap.Index("allocs")
   101  				if err != nil {
   102  					return err
   103  				}
   104  				reply.Index = index
   105  			}
   106  
   107  			// Set the query response
   108  			a.srv.setQueryMeta(&reply.QueryMeta)
   109  			return nil
   110  		}}
   111  	return a.srv.blockingRPC(&opts)
   112  }