Linux Installer Anaconda Analysis (cont.) __linux

Source: Internet
Author: User
Tags gtk

Originally wanted to write an article about Anaconda, but see here to write so detailed, turn, the original text here: Linux Installer Anaconda Analysis (cont.)


(1) disptach.py: Let's take a look at the main interface of the dispatcher class.
1 GoToNext & Gotoprev: These two interfaces move forward (backwards) from the current installation step (back) to the next (previous) with the user interface installation steps, in the graphical interface installation mode, called by the Installcontrolwindow class, in character mode, Called by the Installinterface class (in text.py and cmdline.py). These two functions simply set the orientation of the installation and then call the Movestep function, whose core operation is Movestep.

2) Movestep: We will focus on the analysis of the Movestep function, the code is as follows:

    def movestep (self): if Self.step = = None:self.step = Self.firststep else:if Self.step >= Len (installsteps): Return None log.info ("Leaving (%d) step%s"% (Self._getdir (), installsteps[self.step][0]) Self.step = Self.step + self._getdir () if Self.step >= Len (in Stallsteps): Return None while Self.step >= Self.firststep and Self.step < Len (installsteps ) \ and (Self.stepinskiplist (self.step) or Self.stepisdirect (Self.step)): If Self.stepisdirect (SE
                Lf.step) and not Self.stepinskiplist (self.step): (Stepname, stepfunc) = Installsteps[self.step] Log.info ("Moving (%d) to step%s"% (Self._getdir (), stepname)) Log.debug ("%s are a direct step"% (STE
                    PName,)) rc = Stepfunc (Self.anaconda) if RC in [Dispatch_back, Dispatch_forward]: Self._setdir(RC) Log.info ("Leaving (%d) step%s"% (Self._getdir (), stepname)) # If anything else, leav E self.dir alone self.step = Self.step + self._getdir () If self.step = Len (installsteps): # Installation process 
            Complete, exit Loop return None Self.step < 0: # pick the ' I '  Self.step = 0 while Self.skipSteps.has_key (installsteps[self.step][0]): Self.step
            = self.step + 1 # step number plus one, forward elif self.step >= len (installsteps): Self.step = Len (installsteps)-1 While Self.skipSteps.has_key (Installsteps[self.step][0]): Self.step = self.step-1 Log . info ("Moving (%d) to step%s"% (Self._getdir (), installsteps[self.step][0])

We will focus on the program while loop body, first look at the cyclic condition: when the next installation step is legal, that is, between the first installation step and the last installation step, and (and) the step is skipped or the step is a UI-free installation step, That is, the second element of the Installsteps entry is a function, which enters the loop body. After entering the loop, dispatcher directly calls the function Stepfunc perform the installation operation. If the next installation step still has no user interface, step plus one forward and continue looping until the next installation step with a user interface that has not been skipped, for graphics installation mode, Dispatcher will control power to guid.py in the Installcontrolwindow, for character installation mode, dispatcher will control to Installinterface. Exits the loop if the installation process completes.
3 Currentstep:dispatcher The other main interface of the class, obtains the current installation step and its related information to return to the caller. In the graphics installation mode, this function is mainly called when the Installcontrolwindow scheduling graphical user interface class, in the character mode, mainly in the Installinterface dispatch character user interface, These two classes use this interface to obtain the corresponding class of the user interface for the current installation step and the information needed to create an instance of the user interface class.

 	def currentstep (self):
        if self.step = None:
            self.gotonext ()
        elif self.step >= len (installsteps):
            Return (none, none)

        Stepinfo = Installsteps[self.step] Step
        = stepinfo[0] return

        (step, Self.anaconda)

In addition, the main interface of the Dispatcher class is skipstep (self, steptoskip, skip = 1, permanent = 0) is the function that skips the installation steps. Setsteplist (self, *steps) is the setup step Setup function, which is invoked primarily by an instance of the installation type, and each installation type sets the installation step according to its own characteristics. The implementation logic of these interfaces is relatively simple, here is not a single analysis.
(2) gui.py: The core is the Installinterface class of character installation mode and the realization of Installcontrolwindow class of graphics installation mode. Look at the interface in the Installcontrolwindow.

1 Data Structure Steptopclass: This dictionary records all the installation steps with a graphical user interface in the installation process.

Steptoclass = {"Language": ("Language_gui", "Languagewindow"), "Keyboard": ("Kbd_gui", "Keyboardwindow"), " FilterType ": (" Filter_type "," Filtertypewindow ")," Filter ": (" Filter_gui "," Filterwindow ")," Zfcpconfig ": (" ZF Cp_gui "," Zfcpwindow ")," Partition ": (" Partition_gui "," Partitionwindow ")," PartType ": (" Autopart_type "," Partit Iontypewindow ")," Cleardiskssel ": (" Cleardisks_gui "," Cleardiskswindow ")," Findinstall ": (" Examine_gui "," Upgrade Examinewindow ")," Addswap ": (" Upgrade_swap_gui "," Upgradeswapwindow ")," Upgrademigratefs ": (" Upgrade_migratefs_g UI "," Upgrademigratefswindow ")," bootloader ": (" Bootloader_main_gui "," Mainbootloaderwindow ")," Upgbootloader ": (" Upgrade_bootloader_gui "," Upgradebootloaderwindow ")," Network ": (" Network_gui "," Networkwindow ")," timezone ": (" Timezone_gui "," Timezonewindow ")," Accounts ": (" Account_gui "," Accountwindow ")," Tasksel ": (" Task_gui "," Taskwind ow ")," Group-selEction ": (" Package_gui "," Groupselectionwindow ")," Install ": (" Progress_gui "," Installprogresswindow ")," complete ": (" Congrats_gui "," Congratulationwindow "),}

Each entry from left to right is the name of the installation step, the module of the graphic interface class, and the name of the graphic interface class. If language is the name of the installation step, Language_gui is the module Language_gui.py,languagewindow for the graphical interface class that corresponds to the graphical interface for this step.
2) Run: Starts the entry function of the graphical installation interface. The function calls the Setup_window interface, which calls the main form of the GTK "draw" graphical installation interface, and then control is handed to the GTK

    def run (self):
        self.setup_theme ()
        Self.setup_window (False)
        Gtk.main ()

3 nextclicked & prevclicked: These two interfaces perform the operation from the current graphical installation interface forward (backwards) to the next graphical installation interface, and we can imagine that these two functions are invoked when the user clicks the next or Previous button in the installation process. The two functions first invoke the main process Control dispatcher instance forward (backward) to the next graphical installation interface, and then call the Setscreen function to set the graphical interface.

    def prevclicked (self, *args): Try:self.currentWindow.getPrev () except Stayonscreen:
        Return Self.anaconda.dispatch.gotoPrev () Self.setscreen () def nextclicked (self, *args): TRY:RC = Self.currentWindow.getNext () except Stayonscreen:return SELF.A Naconda.dispatch.gotoNext () Self.setscreen () 4) Setscreen: For setting the graphical interface. The code is as follows: Def setscreen (self): # Get current installation step information (steps, anaconda) = Self.anaconda.dispatch.currentStep () if
            Step is None:gtk.main_quit () return if not steptoclass[step: # No, skip to next
                if Self.anaconda.dispatch.dir = = Dispatch_forward:return self.nextclicked () Else:  Return self.prevclicked () (file, className) = Steptoclass[step] # Get the module of the graphics interface class and its class name Newscreenclass = None while True:try:found = iMp.find_module (file, iw.__path__) modulename = ' pyanaconda.iw.%s '% file loaded = Imp.load
            _module (ModuleName, *found) # Load the graphical interface module Newscreenclass = loaded.__dict__[classname] Break
                Except Importerror, E:stdout_log.error ("Loading interface component%s"% className)
                                    Stdout_log.error (Traceback.format_exc ()) win = MessageWindow (_ ("error!"), 
                                      _ ("An error occurred when attempting" "to the Load an installer interface" 
                                    "Component.\n\nclassname =%s")% (ClassName,), Type= "Custom", custom_icon= "warning", Custom_butt
                    Ons=[_ ("_exit"), _ ("_retry")]) if not WIN.GETRC ():  msg =_ ("The system'll now reboot.")
                                  buttons = [_ ("_reboot")] MessageWindow (_ ("exiting"), MSG,
                                  Type= "Custom", custom_icon= "warning", custom_buttons=buttons) sys.exit (0) ICS = Installcontrolstate (self) # Set whether it is possible to return the previous
        Step ics.setprevenabled (Self.anaconda.dispatch.canGoBack ()) Self.destroycurrentwindow () # Destroy the original graphical installation interface Self.currentwindow = Newscreenclass (ICS) # Creates a new graphical installation interface and is set to the current interface New_screen = Self.currentWindow.getScreen (Anaconda # The interface to build the installation step # If The Getscreen method returned None, which means the screen did not # want to be Displa  Yed for some reason and we should skip to the next # step. However, we don't want to remove the "current step" from the ' # List as later events may cause the ' screen to be disp
        layed. If not new_screen:if Self.anaconda.dispatch.dir = = DISPATCH_FORWARD:self.anaconda.dispatch.gotoNext () Else:self.anaconda.dispatch.gotoPrev () return Self.setscreen () self.upd Ate (ICS) Self.installFrame.add (New_screen) self.installFrame.show_all () SELF.CURRENTWINDOW.FOCU S () Self.handle = Gobject.idle_add (self.handlerendercallback) if SELF.RELOADRCQUEUED:SELF.W Indow.reset_rc_styles () self.reloadrcqueued = 0

The previous nextclicked and prevclicked functions have been marked as the current installation step by dispatcher the installation steps that will be made. So this function first obtains the current installation step name and the related information through the dispatcher Currentstep from the dispatcher data structure installsteps, next, has made the judgment, If the current installation step for dispatcher is not in the dictionary steptoclass, ignore the step and invoke nextclicked or prevclicked to continue with the next graphical installation step until the next step is in the dictionary steptoclass. After validation is passed, get the class of the current graphics installation interface from the dictionary Steptoclass and the module of the class, import the module and create an instance of the graphical installation interface, destroy the previous graphical installation interface, and place the newly created graphical interface instance as the current installation interface. Call the Getscreen function of the graphical installation interface instance to generate a graphical user interface for the installation step, and then display.
At this point, the main logic of Installcontrolwindow has been analyzed, followed by each specific installation interface and its installation operations readers can go to the IW directory for in-depth analysis.
(3) Anaconda Main program: The graphics environment is built on the basis of X server, for graphics mode, Anaconda need to run the X server First, and then start the graphics mode installation process. For character patterns, Anaconda's main executive Body does one thing, starting the character-mode Setup process.

if __name__ = = "__main__": Setuppythonpath () # ... # parsing parameters passed in when starting this script (opts, args) = Parseoptions ()
    From pyanaconda.flags import flags if Opts.images:flags.imageInstall = True # set log import logging From Pyanaconda import anaconda_log anaconda_log.init () log = Logging.getlogger ("Anaconda") Stdoutlog = Lo 
    Gging.getlogger ("Anaconda.stdout") # ... from Pyanaconda import anaconda anaconda = Anaconda () # Create a main body instance 
    warnings.showwarning = anacondashowwarning iutil.setup_translations (gettext) # ... # detecting memory, now used only in text mode Check_memory (Anaconda, opts, ' t ') if Opts.unsupportedMode:stdoutLog.error ("Running Anaconda in%s mode" is no longer supported. "% Opts.unsupportedmode) sys.exit (0) # ... # Kickstart file parse if Opts.ksfile : Kickstart.prescriptpass (Anaconda, opts.ksfile) Anaconda.ksdata = Kickstart.parsekickstart (Anaconda, opts . Ksfile) Opts.reScue = Opts.rescue or Anaconda.ksdata.rescue.rescue # ... # if not x server, use text mode if not Flags.livecdinstall And not iutil.iss390 () and not os.access ("/usr/bin/xorg", OS.
                             X_OK): Stdoutlog.warning (_ ("Graphical installation is not available.")
         "Starting text mode.")  Time.sleep (2) Anaconda.displaymode = ' t ' # ... # start local x server if Anaconda.displaymode = = ' g ' and  Not flags.preexisting_x11 and isn't flags.usevnc:try: # start X with its USR1 handler set to ignore.  This'll make it send # US SIGUSR1 if it succeeds.

            If it fails, catch sigchld and bomb out.

            def sigchld_handler (num, frame): Raise OSError (0, "sigchld caught when trying to start the X server.")

            def sigusr1_handler (num, frame): Log.debug ("X server has signalled a successful start.") Def preexec_fn (): signal.signal (signal. Sigusr1, signal. sig_ign) OLD_SIGUSR1 = signal.signal (signal. SIGUSR1, Sigusr1_handler) old_sigchld = signal.signal (signal. SIGCHLD, Sigchld_handler) xout = open ("/dev/tty5", "W") # starts x server proc = subprocess.
                                     Popen (["Xorg", "-br", "-logfile", "/tmp/x.log", ": 1", "Vt6", "s", "1440", "-ac",
                                     "-nolisten", "TCP", "-dpi", "a", "-noreset"], Close_fds=true, Stdout=xout, Stderr=xout, PREEXEC_FN
        =PREEXEC_FN) Signal.pause () os.environ["DISPLAY" = ": 1" dostartupx11actions ()
            Except (OSError, RuntimeError) as E:stdoutlog.warning ("X startup failed, falling back to text mode")
            Anaconda.displaymode = ' t ' graphical_failed = 1 time.sleep (2) Finally: Signal.signaL (signal. SIGUSR1, OLD_SIGUSR1) signal.signal (signal. SIGCHLD, OLD_SIGCHLD) set_x_resolution (opts.runres) # ... # Initialize UI interface Anaconda.initinterface () Ana Conda.instClass.configure (Anaconda) # ... # Start installation process Try:anaconda.intf.run (anaconda) except Sy Stemexit, Code:anaconda.intf.shutdown () if Anaconda.ksdata and anaconda.ksdata.reboot.eject:for dri ve in Anaconda.storage.devicetree.devices:if drive.type!= "cdrom": Continue Log . info ("Attempting to eject%s"% Drive.path) Drive.eject () del anaconda.intf

The main tasks include referencing module path setting, parameter parsing, setting log, memory detection, installation type setting, and then calling the Pyanaconda/__init__.py::anaconda class to create the main instance anaconda, then parsing the kickstart file, calling The/usr/bin/xorg (in the INSTALL.IMG) program starts X server and invokes the Initinterface () initialization interface of the Anaconda class. Invoke the Run () of the intf (an instance of the Installinterface Class) to start the installation process. For character installation mode, the run interface that directly invokes the Installinterface instance. For graphical installation mode, the run interface of the Installcontrolwindow instance is invoked indirectly by the run interface of the Installinterface instance to start the graphical interface.
(4) pyanaconda/__init__.py: There are Anaconda class, responsible for the specific start of the installation process. Previously said, the installation process by the dispatcher control, for graphics mode, graphics mode front-end display and interaction with the user by Installcontrolwindow scheduling, while the character pattern of the front-end display layer by the Installinterface scheduling. Therefore, the start of the installation process, the actual is to create the main control class instances, invoke the interface of the instance, start the installation process, and then by these main instances of the control class to create a concrete installation interface, create an instance of the installation behavior class, call specific functions to complete the specific installation process.

Class Anaconda (object): Def __init__ (self): import desktop, dispatch, firewall, security import system _config_keyboard.keyboard as keyboard from flags import Flags # ... # Create dispatch instance Self.disp Atch = dispatch. Dispatcher (self) # ... # ... intf = property (_getinterface, _setinterface, _delinterface) #. ... def initinterface (self): if self._intf:raise runtimeerror, "Second attempt to initialize T He installinterface "# Set graphics mode required link if self.displaymode = = ' G ': Stdoutlog.info (_ (" Starting GR

            aphical installation. ") Try:from GUI import installinterface except Exception, E:from flags import F  Lags Stdoutlog.error ("Exception starting GUI Installer:%s"% (E,)) # If we ' re not going to Really go in GUI mode, we need to get # back to Vc1 where the text instalL is going to pops up. If not flags.livecdInstall:isys.vtActivate (1) stdoutlog.warning ("GUI installer start
                Up failed, falling back to text mode. "
                Self.displaymode = ' t ' if ' Display ' in Os.environ.keys (): Del os.environ[' Display '
            Time.sleep (2) if Self.displaymode = = ' t ': From text import installinterface If not Os.environ.has_key ("Lang"): os.environ["lang" = "en_US". UTF-8 "if Self.displaymode = = ' C ': from cmdline import installinterface self._intf = Install Interface () # Create Installinterface instance return self._intf

The main tasks include creating dispatch instances, initializing the interface, creating Installinterface instances, and eventually creating Installcontrolwindow instances to generate graphical interfaces.
The entire anaconda operation process is shown below:

Figure 2 Anaconda Running Process

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.