checksettings.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #
  2. # SPDX-License-Identifier: GPL-2.0-only
  3. #
  4. from django.core.management.base import BaseCommand
  5. from django.core.management import call_command
  6. from bldcontrol.models import BuildRequest, BuildEnvironment, BRError
  7. from orm.models import ToasterSetting, Build, Layer
  8. import os
  9. import traceback
  10. import warnings
  11. def DN(path):
  12. if path is None:
  13. return ""
  14. else:
  15. return os.path.dirname(path)
  16. class Command(BaseCommand):
  17. args = ""
  18. help = "Verifies that the configured settings are valid and usable, or prompts the user to fix the settings."
  19. def __init__(self, *args, **kwargs):
  20. super(Command, self).__init__(*args, **kwargs)
  21. self.guesspath = DN(DN(DN(DN(DN(DN(DN(__file__)))))))
  22. def _verify_build_environment(self):
  23. # provide a local build env. This will be extended later to include non local
  24. if BuildEnvironment.objects.count() == 0:
  25. BuildEnvironment.objects.create(betype=BuildEnvironment.TYPE_LOCAL)
  26. # we make sure we have builddir and sourcedir for all defined build envionments
  27. for be in BuildEnvironment.objects.all():
  28. be.needs_import = False
  29. def _verify_be():
  30. is_changed = False
  31. def _update_sourcedir():
  32. be.sourcedir = os.environ.get('TOASTER_DIR')
  33. return True
  34. if len(be.sourcedir) == 0:
  35. is_changed = _update_sourcedir()
  36. if not be.sourcedir.startswith("/"):
  37. print("\n -- Validation: The layers checkout directory must be set to an absolute path.")
  38. is_changed = _update_sourcedir()
  39. if is_changed:
  40. if be.betype == BuildEnvironment.TYPE_LOCAL:
  41. be.needs_import = True
  42. return True
  43. def _update_builddir():
  44. be.builddir = os.environ.get('TOASTER_DIR')+"/build"
  45. return True
  46. if len(be.builddir) == 0:
  47. is_changed = _update_builddir()
  48. if not be.builddir.startswith("/"):
  49. print("\n -- Validation: The build directory must to be set to an absolute path.")
  50. is_changed = _update_builddir()
  51. if is_changed:
  52. print("\nBuild configuration saved")
  53. be.save()
  54. return True
  55. if be.needs_import:
  56. try:
  57. print("Loading default settings")
  58. call_command("loaddata", "settings")
  59. template_conf = os.environ.get("TEMPLATECONF", "")
  60. custom_xml_only = os.environ.get("CUSTOM_XML_ONLY")
  61. if ToasterSetting.objects.filter(name='CUSTOM_XML_ONLY').count() > 0 or custom_xml_only is not None:
  62. # only use the custom settings
  63. pass
  64. elif "poky" in template_conf:
  65. print("Loading poky configuration")
  66. call_command("loaddata", "poky")
  67. else:
  68. print("Loading OE-Core configuration")
  69. call_command("loaddata", "oe-core")
  70. if template_conf:
  71. oe_core_path = os.path.realpath(
  72. template_conf +
  73. "/../")
  74. else:
  75. print("TEMPLATECONF not found. You may have to"
  76. " manually configure layer paths")
  77. oe_core_path = input("Please enter the path of"
  78. " your openembedded-core "
  79. "layer: ")
  80. # Update the layer instances of openemebedded-core
  81. for layer in Layer.objects.filter(
  82. name="openembedded-core",
  83. local_source_dir="OE-CORE-LAYER-DIR"):
  84. layer.local_path = oe_core_path
  85. layer.save()
  86. # Import the custom fixture if it's present
  87. with warnings.catch_warnings():
  88. warnings.filterwarnings(
  89. action="ignore",
  90. message="^.*No fixture named.*$")
  91. print("Importing custom settings if present")
  92. try:
  93. call_command("loaddata", "custom")
  94. except:
  95. print("NOTE: optional fixture 'custom' not found")
  96. # we run lsupdates after config update
  97. print("\nFetching information from the layer index, "
  98. "please wait.\nYou can re-update any time later "
  99. "by running bitbake/lib/toaster/manage.py "
  100. "lsupdates\n")
  101. call_command("lsupdates")
  102. # we don't look for any other config files
  103. return is_changed
  104. except Exception as e:
  105. print("Failure while trying to setup toaster: %s"
  106. % e)
  107. traceback.print_exc()
  108. return is_changed
  109. while _verify_be():
  110. pass
  111. return 0
  112. def _verify_default_settings(self):
  113. # verify that default settings are there
  114. if ToasterSetting.objects.filter(name='DEFAULT_RELEASE').count() != 1:
  115. ToasterSetting.objects.filter(name='DEFAULT_RELEASE').delete()
  116. ToasterSetting.objects.get_or_create(name='DEFAULT_RELEASE', value='')
  117. return 0
  118. def _verify_builds_in_progress(self):
  119. # we are just starting up. we must not have any builds in progress, or build environments taken
  120. for b in BuildRequest.objects.filter(state=BuildRequest.REQ_INPROGRESS):
  121. BRError.objects.create(req=b, errtype="toaster",
  122. errmsg=
  123. "Toaster found this build IN PROGRESS while Toaster started up. This is an inconsistent state, and the build was marked as failed")
  124. BuildRequest.objects.filter(state=BuildRequest.REQ_INPROGRESS).update(state=BuildRequest.REQ_FAILED)
  125. BuildEnvironment.objects.update(lock=BuildEnvironment.LOCK_FREE)
  126. # also mark "In Progress builds as failures"
  127. from django.utils import timezone
  128. Build.objects.filter(outcome=Build.IN_PROGRESS).update(outcome=Build.FAILED, completed_on=timezone.now())
  129. return 0
  130. def handle(self, **options):
  131. retval = 0
  132. retval += self._verify_build_environment()
  133. retval += self._verify_default_settings()
  134. retval += self._verify_builds_in_progress()
  135. return retval