github.com/rancher/longhorn-engine@v0.6.2/replica/rpc/server.go (about)

     1  package rpc
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  
     7  	"github.com/golang/protobuf/ptypes/empty"
     8  	"golang.org/x/net/context"
     9  	healthpb "google.golang.org/grpc/health/grpc_health_v1"
    10  
    11  	"github.com/longhorn/longhorn-engine/replica"
    12  )
    13  
    14  type ReplicaServer struct {
    15  	s *replica.Server
    16  }
    17  
    18  type ReplicaHealthCheckServer struct {
    19  	rs *ReplicaServer
    20  }
    21  
    22  func NewReplicaServer(s *replica.Server) *ReplicaServer {
    23  	return &ReplicaServer{
    24  		s: s,
    25  	}
    26  }
    27  
    28  func NewReplicaHealthCheckServer(rs *ReplicaServer) *ReplicaHealthCheckServer {
    29  	return &ReplicaHealthCheckServer{
    30  		rs: rs,
    31  	}
    32  }
    33  
    34  func (rs *ReplicaServer) listReplicaDisks() map[string]*DiskInfo {
    35  	disks := map[string]*DiskInfo{}
    36  	r := rs.s.Replica()
    37  	if r != nil {
    38  		ds := r.ListDisks()
    39  		for name, info := range ds {
    40  			disks[name] = &DiskInfo{
    41  				Name:        info.Name,
    42  				Parent:      info.Parent,
    43  				Children:    info.Children,
    44  				Removed:     info.Removed,
    45  				UserCreated: info.UserCreated,
    46  				Created:     info.Created,
    47  				Size:        info.Size,
    48  				Labels:      info.Labels,
    49  			}
    50  		}
    51  	}
    52  	return disks
    53  }
    54  
    55  func (rs *ReplicaServer) getReplica() (replica *Replica) {
    56  	state, info := rs.s.Status()
    57  	replica = &Replica{
    58  		Dirty:       info.Dirty,
    59  		Rebuilding:  info.Rebuilding,
    60  		Head:        info.Head,
    61  		Parent:      info.Parent,
    62  		Size:        strconv.FormatInt(info.Size, 10),
    63  		SectorSize:  info.SectorSize,
    64  		BackingFile: info.BackingFileName,
    65  		State:       string(state),
    66  		Disks:       rs.listReplicaDisks(),
    67  	}
    68  	r := rs.s.Replica()
    69  	if r != nil {
    70  		chain, _ := r.DisplayChain()
    71  		replica.Chain = chain
    72  		replica.RemainSnapshots = int32(r.GetRemainSnapshotCounts())
    73  		replica.RevisionCounter = r.GetRevisionCounter()
    74  	}
    75  	return replica
    76  }
    77  
    78  func (rs *ReplicaServer) ReplicaCreate(ctx context.Context, req *ReplicaCreateRequest) (*Replica, error) {
    79  	size := int64(0)
    80  	if req.Size != "" {
    81  		var err error
    82  		size, err = strconv.ParseInt(req.Size, 10, 0)
    83  		if err != nil {
    84  			return nil, err
    85  		}
    86  	}
    87  
    88  	if err := rs.s.Create(size); err != nil {
    89  		return nil, err
    90  	}
    91  
    92  	return rs.getReplica(), nil
    93  }
    94  
    95  func (rs *ReplicaServer) ReplicaDelete(ctx context.Context, req *empty.Empty) (*empty.Empty, error) {
    96  	return &empty.Empty{}, rs.s.Delete()
    97  }
    98  
    99  func (rs *ReplicaServer) ReplicaGet(ctx context.Context, req *empty.Empty) (*Replica, error) {
   100  	return rs.getReplica(), nil
   101  }
   102  
   103  func (rs *ReplicaServer) ReplicaOpen(ctx context.Context, req *empty.Empty) (*Replica, error) {
   104  	if err := rs.s.Open(); err != nil {
   105  		return nil, err
   106  	}
   107  
   108  	return rs.getReplica(), nil
   109  }
   110  
   111  func (rs *ReplicaServer) ReplicaClose(ctx context.Context, req *empty.Empty) (*Replica, error) {
   112  	if err := rs.s.Close(); err != nil {
   113  		return nil, err
   114  	}
   115  
   116  	return rs.getReplica(), nil
   117  }
   118  
   119  func (rs *ReplicaServer) ReplicaReload(ctx context.Context, req *empty.Empty) (*Replica, error) {
   120  	if err := rs.s.Reload(); err != nil {
   121  		return nil, err
   122  	}
   123  
   124  	return rs.getReplica(), nil
   125  }
   126  
   127  func (rs *ReplicaServer) ReplicaRevert(ctx context.Context, req *ReplicaRevertRequest) (*Replica, error) {
   128  	if req.Name == "" {
   129  		return nil, fmt.Errorf("Cannot accept empty snapshot name")
   130  	}
   131  	if req.Created == "" {
   132  		return nil, fmt.Errorf("Need to specific created time")
   133  	}
   134  
   135  	if err := rs.s.Revert(req.Name, req.Created); err != nil {
   136  		return nil, err
   137  	}
   138  
   139  	return rs.getReplica(), nil
   140  }
   141  
   142  func (rs *ReplicaServer) ReplicaSnapshot(ctx context.Context, req *ReplicaSnapshotRequest) (*Replica, error) {
   143  	if req.Name == "" {
   144  		return nil, fmt.Errorf("Cannot accept empty snapshot name")
   145  	}
   146  	if req.Created == "" {
   147  		return nil, fmt.Errorf("Need to specific created time")
   148  	}
   149  
   150  	if err := rs.s.Snapshot(req.Name, req.UserCreated, req.Created, req.Labels); err != nil {
   151  		return nil, err
   152  	}
   153  
   154  	return rs.getReplica(), nil
   155  }
   156  
   157  func (rs *ReplicaServer) DiskRemove(ctx context.Context, req *DiskRemoveRequest) (*Replica, error) {
   158  	if err := rs.s.RemoveDiffDisk(req.Name, req.Force); err != nil {
   159  		return nil, err
   160  	}
   161  
   162  	return rs.getReplica(), nil
   163  }
   164  
   165  func (rs *ReplicaServer) DiskReplace(ctx context.Context, req *DiskReplaceRequest) (*Replica, error) {
   166  	if err := rs.s.ReplaceDisk(req.Target, req.Source); err != nil {
   167  		return nil, err
   168  	}
   169  
   170  	return rs.getReplica(), nil
   171  }
   172  
   173  func (rs *ReplicaServer) DiskPrepareRemove(ctx context.Context, req *DiskPrepareRemoveRequest) (*DiskPrepareRemoveReply, error) {
   174  	operations, err := rs.s.PrepareRemoveDisk(req.Name)
   175  	if err != nil {
   176  		return nil, err
   177  	}
   178  
   179  	reply := &DiskPrepareRemoveReply{}
   180  	for _, op := range operations {
   181  		reply.Operations = append(reply.Operations, &PrepareRemoveAction{
   182  			Action: op.Action,
   183  			Source: op.Source,
   184  			Target: op.Target,
   185  		})
   186  	}
   187  	return reply, err
   188  }
   189  
   190  func (rs *ReplicaServer) DiskMarkAsRemoved(ctx context.Context, req *DiskMarkAsRemovedRequest) (*Replica, error) {
   191  	if err := rs.s.MarkDiskAsRemoved(req.Name); err != nil {
   192  		return nil, err
   193  	}
   194  
   195  	return rs.getReplica(), nil
   196  }
   197  
   198  func (rs *ReplicaServer) RebuildingSet(ctx context.Context, req *RebuildingSetRequest) (*Replica, error) {
   199  	if err := rs.s.SetRebuilding(req.Rebuilding); err != nil {
   200  		return nil, err
   201  	}
   202  
   203  	return rs.getReplica(), nil
   204  }
   205  
   206  func (rs *ReplicaServer) RevisionCounterSet(ctx context.Context, req *RevisionCounterSetRequest) (*Replica, error) {
   207  	if err := rs.s.SetRevisionCounter(req.Counter); err != nil {
   208  		return nil, err
   209  	}
   210  	return rs.getReplica(), nil
   211  }
   212  
   213  func (hc *ReplicaHealthCheckServer) Check(context.Context, *healthpb.HealthCheckRequest) (*healthpb.HealthCheckResponse, error) {
   214  	if hc.rs.s != nil {
   215  		return &healthpb.HealthCheckResponse{
   216  			Status: healthpb.HealthCheckResponse_SERVING,
   217  		}, nil
   218  	}
   219  
   220  	return &healthpb.HealthCheckResponse{
   221  		Status: healthpb.HealthCheckResponse_NOT_SERVING,
   222  	}, nil
   223  }
   224  
   225  func (hc *ReplicaHealthCheckServer) Watch(req *healthpb.HealthCheckRequest, ws healthpb.Health_WatchServer) error {
   226  	if hc.rs.s != nil {
   227  		return ws.Send(&healthpb.HealthCheckResponse{
   228  			Status: healthpb.HealthCheckResponse_SERVING,
   229  		})
   230  	}
   231  
   232  	return ws.Send(&healthpb.HealthCheckResponse{
   233  		Status: healthpb.HealthCheckResponse_NOT_SERVING,
   234  	})
   235  }