/internal/app/singularity/oci_create_linux.go

https://github.com/sylabs/singularity · Go · 81 lines · 60 code · 15 blank · 6 comment · 12 complexity · 765b502fc10ae209ab9228f9cbb5f5fb MD5 · raw file

  1. // Copyright (c) 2018-2020, Sylabs Inc. All rights reserved.
  2. // This software is licensed under a 3-clause BSD license. Please consult the
  3. // LICENSE.md file distributed with the sources of this project regarding your
  4. // rights to use or distribute this software.
  5. package singularity
  6. import (
  7. "encoding/json"
  8. "fmt"
  9. "io/ioutil"
  10. "os"
  11. "path/filepath"
  12. "github.com/sylabs/singularity/internal/pkg/runtime/engine/config/oci/generate"
  13. "github.com/sylabs/singularity/internal/pkg/runtime/engine/oci"
  14. "github.com/sylabs/singularity/internal/pkg/util/starter"
  15. "github.com/sylabs/singularity/pkg/runtime/engine/config"
  16. )
  17. // OciCreate creates a container from an OCI bundle
  18. func OciCreate(containerID string, args *OciArgs) error {
  19. _, err := getState(containerID)
  20. if err == nil {
  21. return fmt.Errorf("%s already exists", containerID)
  22. }
  23. os.Clearenv()
  24. absBundle, err := filepath.Abs(args.BundlePath)
  25. if err != nil {
  26. return fmt.Errorf("failed to determine bundle absolute path: %s", err)
  27. }
  28. if err := os.Chdir(absBundle); err != nil {
  29. return fmt.Errorf("failed to change directory to %s: %s", absBundle, err)
  30. }
  31. engineConfig := oci.NewConfig()
  32. generator := generate.New(&engineConfig.OciConfig.Spec)
  33. engineConfig.SetBundlePath(absBundle)
  34. engineConfig.SetLogPath(args.LogPath)
  35. engineConfig.SetLogFormat(args.LogFormat)
  36. engineConfig.SetPidFile(args.PidFile)
  37. // load config.json from bundle path
  38. configJSON := filepath.Join(absBundle, "config.json")
  39. fb, err := os.Open(configJSON)
  40. if err != nil {
  41. return fmt.Errorf("oci specification file %q is missing or cannot be read", configJSON)
  42. }
  43. data, err := ioutil.ReadAll(fb)
  44. if err != nil {
  45. return fmt.Errorf("failed to read OCI specification file %s: %s", configJSON, err)
  46. }
  47. fb.Close()
  48. if err := json.Unmarshal(data, generator.Config); err != nil {
  49. return fmt.Errorf("failed to parse OCI specification file %s: %s", configJSON, err)
  50. }
  51. engineConfig.EmptyProcess = args.EmptyProcess
  52. engineConfig.SyncSocket = args.SyncSocketPath
  53. commonConfig := &config.Common{
  54. ContainerID: containerID,
  55. EngineName: oci.Name,
  56. EngineConfig: engineConfig,
  57. }
  58. procName := fmt.Sprintf("Singularity OCI %s", containerID)
  59. return starter.Run(
  60. procName,
  61. commonConfig,
  62. starter.WithStdin(os.Stdin),
  63. starter.WithStderr(os.Stderr),
  64. starter.WithStdout(os.Stdout),
  65. )
  66. }