github.com/maier/nomad@v0.4.1-0.20161110003312-a9e3d0b8549d/nomad/alloc_endpoint.go (about)

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