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