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 }