func NewBox(ctx context.Context, cfg isolate.BoxConfig) (isolate.Box, error) { spoolPath, ok := cfg["spool"].(string) if !ok { spoolPath = defaultSpoolPath } var locator []string if endpoint, ok := cfg["locator"].(string); ok { locator = append(locator, endpoint) } ctx, cancel := context.WithCancel(ctx) box := &Box{ ctx: ctx, cancellation: cancel, spoolPath: spoolPath, storage: createCodeStorage(locator), children: make(map[int]*exec.Cmd), // NOTE: configurable spawnSm: semaphore.New(10), } box.wg.Add(1) go func() { defer box.wg.Done() box.sigchldHandler() }() return box, nil }
// NewBox ... func NewBox(ctx context.Context, cfg isolate.BoxConfig) (isolate.Box, error) { var config = &dockerBoxConfig{ DockerEndpoint: client.DefaultDockerHost, SpawnConcurrency: defaultSpawnConcurrency, } decoderConfig := mapstructure.DecoderConfig{ WeaklyTypedInput: true, Result: config, TagName: "json", } decoder, err := mapstructure.NewDecoder(&decoderConfig) if err != nil { return nil, err } if err = decoder.Decode(cfg); err != nil { return nil, err } client, err := client.NewClient(config.DockerEndpoint, config.APIVersion, nil, defaultHeaders) if err != nil { return nil, err } ctx, cancellation := context.WithCancel(ctx) box := &Box{ ctx: ctx, cancellation: cancellation, client: client, spawnSM: semaphore.New(config.SpawnConcurrency), config: config, containers: make(map[string]*process), } body, err := json.Marshal(config) if err != nil { return nil, err } dockerConfig.Set(string(body)) go box.watchEvents() return box, nil }
// NewBox creates new Box func NewBox(ctx context.Context, cfg isolate.BoxConfig) (isolate.Box, error) { apexctx.GetLogger(ctx).Warn("Porto Box is unstable") var config = &portoBoxConfig{ SpawnConcurrency: 10, DialRetries: 10, CleanupEnabled: true, WeakEnabled: false, } decoderConfig := mapstructure.DecoderConfig{ WeaklyTypedInput: true, Result: config, TagName: "json", } decoder, err := mapstructure.NewDecoder(&decoderConfig) if err != nil { return nil, err } if err = decoder.Decode(cfg); err != nil { return nil, err } if config.Layers == "" { return nil, fmt.Errorf("option Layers is invalid or unspecified") } if config.Containers == "" { return nil, fmt.Errorf("option Containers is invalid or unspecified") } if config.Journal == "" { return nil, fmt.Errorf("option Journal is empty or unspecified") } if config.VolumeBackend == "" { config.VolumeBackend = defaultVolumeBackend } apexctx.GetLogger(ctx).WithField("dir", config.Layers).Info("create directory for Layers") if err = os.MkdirAll(config.Layers, 0755); err != nil { return nil, err } apexctx.GetLogger(ctx).WithField("dir", config.Containers).Info("create directory for Containers") if err = os.MkdirAll(config.Containers, 0755); err != nil { return nil, err } blobRepo, err := NewBlobRepository(ctx, BlobRepositoryConfig{SpoolPath: config.Layers}) if err != nil { return nil, err } tr := &http.Transport{ Dial: func(network, addr string) (net.Conn, error) { for i := 0; i <= config.DialRetries; i++ { dialer := net.Dialer{ DualStack: true, Timeout: 5 * time.Second, } conn, err := dialer.Dial(network, addr) if err == nil { return conn, err } sleepTime := time.Duration(rand.Int63n(500)) * time.Millisecond apexctx.GetLogger(ctx).WithError(err).Errorf("dial error to %s %s. Sleep %v", network, addr, sleepTime) time.Sleep(sleepTime) } return nil, fmt.Errorf("no retries available") }, } portoConn, err := portoConnect() if err != nil { return nil, err } defer portoConn.Close() rootPrefix, err := portoConn.GetProperty("self", "absolute_name") if err != nil { return nil, err } if rootPrefix == "/" { rootPrefix = "" } ctx, onClose := context.WithCancel(ctx) box := &Box{ config: config, journal: newJournal(), transport: tr, spawnSM: semaphore.New(config.SpawnConcurrency), containers: make(map[string]*container), onClose: onClose, rootPrefix: rootPrefix, blobRepo: blobRepo, } body, err := json.Marshal(config) if err != nil { return nil, err } portoConfig.Set(string(body)) if err = box.loadJournal(ctx); err != nil { box.Close() return nil, err } layers, err := portoConn.ListLayers() if err != nil { return nil, err } box.journal.UpdateFromPorto(layers) journalContent.Set(box.journal.String()) go box.waitLoop(ctx) go box.dumpJournalEvery(ctx, time.Minute) return box, nil }