github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/sandbox_store.go (about)

     1  package libnetwork
     2  
     3  import (
     4  	"container/heap"
     5  	"encoding/json"
     6  	"sync"
     7  
     8  	"github.com/Sirupsen/logrus"
     9  	"github.com/docker/libnetwork/datastore"
    10  	"github.com/docker/libnetwork/osl"
    11  )
    12  
    13  const (
    14  	sandboxPrefix = "sandbox"
    15  )
    16  
    17  type epState struct {
    18  	Eid string
    19  	Nid string
    20  }
    21  
    22  type sbState struct {
    23  	ID         string
    24  	Cid        string
    25  	c          *controller
    26  	dbIndex    uint64
    27  	dbExists   bool
    28  	Eps        []epState
    29  	EpPriority map[string]int
    30  	ExtDNS     []string
    31  }
    32  
    33  func (sbs *sbState) Key() []string {
    34  	return []string{sandboxPrefix, sbs.ID}
    35  }
    36  
    37  func (sbs *sbState) KeyPrefix() []string {
    38  	return []string{sandboxPrefix}
    39  }
    40  
    41  func (sbs *sbState) Value() []byte {
    42  	b, err := json.Marshal(sbs)
    43  	if err != nil {
    44  		return nil
    45  	}
    46  	return b
    47  }
    48  
    49  func (sbs *sbState) SetValue(value []byte) error {
    50  	return json.Unmarshal(value, sbs)
    51  }
    52  
    53  func (sbs *sbState) Index() uint64 {
    54  	sbi, err := sbs.c.SandboxByID(sbs.ID)
    55  	if err != nil {
    56  		return sbs.dbIndex
    57  	}
    58  
    59  	sb := sbi.(*sandbox)
    60  	maxIndex := sb.dbIndex
    61  	if sbs.dbIndex > maxIndex {
    62  		maxIndex = sbs.dbIndex
    63  	}
    64  
    65  	return maxIndex
    66  }
    67  
    68  func (sbs *sbState) SetIndex(index uint64) {
    69  	sbs.dbIndex = index
    70  	sbs.dbExists = true
    71  
    72  	sbi, err := sbs.c.SandboxByID(sbs.ID)
    73  	if err != nil {
    74  		return
    75  	}
    76  
    77  	sb := sbi.(*sandbox)
    78  	sb.dbIndex = index
    79  	sb.dbExists = true
    80  }
    81  
    82  func (sbs *sbState) Exists() bool {
    83  	if sbs.dbExists {
    84  		return sbs.dbExists
    85  	}
    86  
    87  	sbi, err := sbs.c.SandboxByID(sbs.ID)
    88  	if err != nil {
    89  		return false
    90  	}
    91  
    92  	sb := sbi.(*sandbox)
    93  	return sb.dbExists
    94  }
    95  
    96  func (sbs *sbState) Skip() bool {
    97  	return false
    98  }
    99  
   100  func (sbs *sbState) New() datastore.KVObject {
   101  	return &sbState{c: sbs.c}
   102  }
   103  
   104  func (sbs *sbState) CopyTo(o datastore.KVObject) error {
   105  	dstSbs := o.(*sbState)
   106  	dstSbs.c = sbs.c
   107  	dstSbs.ID = sbs.ID
   108  	dstSbs.Cid = sbs.Cid
   109  	dstSbs.dbIndex = sbs.dbIndex
   110  	dstSbs.dbExists = sbs.dbExists
   111  	dstSbs.EpPriority = sbs.EpPriority
   112  
   113  	for _, eps := range sbs.Eps {
   114  		dstSbs.Eps = append(dstSbs.Eps, eps)
   115  	}
   116  
   117  	for _, dns := range sbs.ExtDNS {
   118  		dstSbs.ExtDNS = append(dstSbs.ExtDNS, dns)
   119  	}
   120  
   121  	return nil
   122  }
   123  
   124  func (sbs *sbState) DataScope() string {
   125  	return datastore.LocalScope
   126  }
   127  
   128  func (sb *sandbox) storeUpdate() error {
   129  	sbs := &sbState{
   130  		c:          sb.controller,
   131  		ID:         sb.id,
   132  		Cid:        sb.containerID,
   133  		EpPriority: sb.epPriority,
   134  		ExtDNS:     sb.extDNS,
   135  	}
   136  
   137  retry:
   138  	sbs.Eps = nil
   139  	for _, ep := range sb.getConnectedEndpoints() {
   140  		// If the endpoint is not persisted then do not add it to
   141  		// the sandbox checkpoint
   142  		if ep.Skip() {
   143  			continue
   144  		}
   145  
   146  		eps := epState{
   147  			Nid: ep.getNetwork().ID(),
   148  			Eid: ep.ID(),
   149  		}
   150  
   151  		sbs.Eps = append(sbs.Eps, eps)
   152  	}
   153  
   154  	err := sb.controller.updateToStore(sbs)
   155  	if err == datastore.ErrKeyModified {
   156  		// When we get ErrKeyModified it is sufficient to just
   157  		// go back and retry.  No need to get the object from
   158  		// the store because we always regenerate the store
   159  		// state from in memory sandbox state
   160  		goto retry
   161  	}
   162  
   163  	return err
   164  }
   165  
   166  func (sb *sandbox) storeDelete() error {
   167  	sbs := &sbState{
   168  		c:        sb.controller,
   169  		ID:       sb.id,
   170  		Cid:      sb.containerID,
   171  		dbIndex:  sb.dbIndex,
   172  		dbExists: sb.dbExists,
   173  	}
   174  
   175  	return sb.controller.deleteFromStore(sbs)
   176  }
   177  
   178  func (c *controller) sandboxCleanup(activeSandboxes map[string]interface{}) {
   179  	store := c.getStore(datastore.LocalScope)
   180  	if store == nil {
   181  		logrus.Errorf("Could not find local scope store while trying to cleanup sandboxes")
   182  		return
   183  	}
   184  
   185  	kvol, err := store.List(datastore.Key(sandboxPrefix), &sbState{c: c})
   186  	if err != nil && err != datastore.ErrKeyNotFound {
   187  		logrus.Errorf("failed to get sandboxes for scope %s: %v", store.Scope(), err)
   188  		return
   189  	}
   190  
   191  	// It's normal for no sandboxes to be found. Just bail out.
   192  	if err == datastore.ErrKeyNotFound {
   193  		return
   194  	}
   195  
   196  	for _, kvo := range kvol {
   197  		sbs := kvo.(*sbState)
   198  
   199  		sb := &sandbox{
   200  			id:                 sbs.ID,
   201  			controller:         sbs.c,
   202  			containerID:        sbs.Cid,
   203  			endpoints:          epHeap{},
   204  			populatedEndpoints: map[string]struct{}{},
   205  			dbIndex:            sbs.dbIndex,
   206  			isStub:             true,
   207  			dbExists:           true,
   208  			extDNS:             sbs.ExtDNS,
   209  		}
   210  
   211  		msg := " for cleanup"
   212  		create := true
   213  		isRestore := false
   214  		if val, ok := activeSandboxes[sb.ID()]; ok {
   215  			msg = ""
   216  			sb.isStub = false
   217  			isRestore = true
   218  			opts := val.([]SandboxOption)
   219  			sb.processOptions(opts...)
   220  			sb.restorePath()
   221  			create = !sb.config.useDefaultSandBox
   222  			heap.Init(&sb.endpoints)
   223  		}
   224  		sb.osSbox, err = osl.NewSandbox(sb.Key(), create, isRestore)
   225  		if err != nil {
   226  			logrus.Errorf("failed to create osl sandbox while trying to restore sandbox %s%s: %v", sb.ID()[0:7], msg, err)
   227  			continue
   228  		}
   229  
   230  		c.Lock()
   231  		c.sandboxes[sb.id] = sb
   232  		c.Unlock()
   233  
   234  		for _, eps := range sbs.Eps {
   235  			n, err := c.getNetworkFromStore(eps.Nid)
   236  			var ep *endpoint
   237  			if err != nil {
   238  				logrus.Errorf("getNetworkFromStore for nid %s failed while trying to build sandbox for cleanup: %v", eps.Nid, err)
   239  				n = &network{id: eps.Nid, ctrlr: c, drvOnce: &sync.Once{}, persist: true}
   240  				ep = &endpoint{id: eps.Eid, network: n, sandboxID: sbs.ID}
   241  			} else {
   242  				ep, err = n.getEndpointFromStore(eps.Eid)
   243  				if err != nil {
   244  					logrus.Errorf("getEndpointFromStore for eid %s failed while trying to build sandbox for cleanup: %v", eps.Eid, err)
   245  					ep = &endpoint{id: eps.Eid, network: n, sandboxID: sbs.ID}
   246  				}
   247  			}
   248  			if _, ok := activeSandboxes[sb.ID()]; ok && err != nil {
   249  				logrus.Errorf("failed to restore endpoint %s in %s for container %s due to %v", eps.Eid, eps.Nid, sb.ContainerID(), err)
   250  				continue
   251  			}
   252  			heap.Push(&sb.endpoints, ep)
   253  		}
   254  
   255  		if _, ok := activeSandboxes[sb.ID()]; !ok {
   256  			logrus.Infof("Removing stale sandbox %s (%s)", sb.id, sb.containerID)
   257  			if err := sb.delete(true); err != nil {
   258  				logrus.Errorf("Failed to delete sandbox %s while trying to cleanup: %v", sb.id, err)
   259  			}
   260  			continue
   261  		}
   262  
   263  		// reconstruct osl sandbox field
   264  		if !sb.config.useDefaultSandBox {
   265  			if err := sb.restoreOslSandbox(); err != nil {
   266  				logrus.Errorf("failed to populate fields for osl sandbox %s", sb.ID())
   267  				continue
   268  			}
   269  		} else {
   270  			c.sboxOnce.Do(func() {
   271  				c.defOsSbox = sb.osSbox
   272  			})
   273  		}
   274  
   275  		for _, ep := range sb.endpoints {
   276  			// Watch for service records
   277  			if !c.isAgent() {
   278  				c.watchSvcRecord(ep)
   279  			}
   280  		}
   281  	}
   282  }