Esempio n. 1
0
 def __init__(self):
     self.name = self.__module__.split(".")[-1]
     self.wd = xmltools.WorkerDescription(self.name, prefix="/status")
     self.config_elt = self._get_config()
     self.cache_dir = os.path.join(context.cache_dir(), "bundles")
     try:
         os.mkdir(self.cache_dir)
     except OSError as e:
         if e.errno == errno.EEXIST:
             # don't worry about it
             pass
     self.cache_maint()
Esempio n. 2
0
    def __init__(self, datadir=None):
        if datadir:
            self.datadir = datadir
        else:
            self.datadir = os.path.join(context.cache_dir(),
                                        'workers',
                                        'dummyordered')
        self.wd = xmltools.WorkerDescription("dummyordered",
                                             prefix='/status')
        self.pdb = pretend_db(os.path.join(self.datadir, "pdb"))
        self.pc = pretend_config(os.path.join(self.datadir, "conf.txt"))

        self.dispatch = {
            '/status/worker/sysitem': self.handle_ordered,
            '/status/worker/tofile': self.handle_file,
            '/status/worker/notordered': self.handle_notordered,
            }
Esempio n. 3
0
    def _process(self, work, operation):
        # Prep necessary variables
        type = work.xpath('pkginfo/@type')[0]
        bundle = work.xpath('machinationFetcherBundle/@id')[0]
        bundle_path = os.path.join(context.cache_dir(),
                                   'bundles',
                                   bundle)
        if "interactive" in work.keys():
            inter = work.attrib["interactive"]
        else:
            inter = False

        # If it's interactive and not MSI, we need an uninstall check
        if inter and (type != "msi"):
            if not work.find("check"):
                err = "Interactive package without installation check: "
                err += bundle
                l.emsg(err)
                res.attrib["status"] = "error"
                res.attrib["message"] = err
                return res
            ins_check = [work.xpath('check/@type')[0],
                         work.xpath('check/@id')[0]]
        else:
            ins_check = None

        # MSIs have additional options in pkginfo
        if type == "msi":
            pkginfo = work.find("pkginfo")
        else:
            pkginfo = None

        op = "_{0}_{1}".format(operation, type)

        back = getattr(self, op)(bundle_path, pkginfo, ins_check, inter)

        if not back:
            open(os.path.join(bundle_path,'.done'), 'a').close()

        return back
Esempio n. 4
0
    def _add(self, work):
        res = etree.Element("wu",
                            id=work.attrib["id"])

        cmdopts = {'printerName': ['/x', '/n', work[0].get("id") ],
                   'remotePath': ['/r', work[0].xpath('remotePath')[0].text ],
                   'model': ['/m', work[0].xpath('model')[0].text ]}

        # Start building a printui command
        printer = [os.path.join(
                   os.environ.get('SYSTEMROOT', os.path.join('C:', 'Windows')),
                   'system32', 'printui.exe')]
        # Use staged driver driver.
        printer.append('/u')
        # Construct human readable printer name ('base' name in
        # windows, hence /b).
        printer.extend(
            [
                '/b',
                self.descriptive_name(work[0])
                ]
            )
        # Queue name.
        printer.extend(['/n', work[0].get("id")])
        # 'Remote path' = port, url or path to print server queue
        printer.extend(['/r', work[0].xpath('remotePath')[0].text ])

        # Now we need model information. We'll need to get that from
        # context.desired_status. Outside of Machination a wrapper
        # script will need to supply a fake context.
        printer_model = work[0].xpath(
            'model/text()'
            )[0]
        xp = '/status/worker[@id="printer"]/model[@id="%s"]' % printer_model
        model_elt = context.desired_status.getroot().xpath(xp)[0]

        # Normally the driver name is the same as the model_elt id. In
        # exceptional circumstances it may be necessary to set
        # something different. In that case there should be a
        # driverName child of model.
        try:
            driverName = model_elt.xpath("driverName/text()")[0]
        except IndexError:
            driverName = model_elt.get("id")
        printer.extend(['/m',driverName])

        # Handle inf path differently depending on whether the driver
        # is built in or needed to be downloaded.
        bundle_elts = model_elt.xpath('machinationFetcherBundle')
        if bundle_elts:
            # We needed to download it. Fetcher should have done the
            # download already, we just have to point to the file
            printer.extend(
                [
                    '/if', '/f',
                    os.path.join(context.cache_dir(),
                                 "bundles",
                                 bundle_elts[0].get("id"),
                                 model_elt.xpath('infFile/text()')[0])
                    ]
                )
            print(model_elt.xpath('infLocation/text()'))
            bundle_elts_inf = model_elt.xpath('infLocation')
            if bundle_elts_inf:
                printer.extend(
                    [
                        '/l',
                        os.path.join(context.cache_dir(),
                                     "bundles",
                                     bundle_elts[0].get("id"),
                                     model_elt.xpath('infLocation/text()')[0])
                        ]
                    )
        else:
            # No bundles: builtin driver.
            printer.extend(
                [
                    '/if', '/f',
                    os.path.join(
                        os.environ.get('windir'),'inf', 'ntprint.inf'
                        )
                    ]
                )

        print(printer)
        #after parsing the xml go and add that printer
        return_code = self.print_ui(printer)

        #check the return code from processAdd
        if return_code:
            res.attrib["status"] = "error"
        else:
            res.attrib["status"] = "success"

        return res
Esempio n. 5
0
    def self_update(self, wu):
        """Perform a Machination self update.

        Sequence:
          - Copy bin_dir()/self_update to cache_dir()
          - Write installedVersion to cache_dir()/installed_version.xml
          - os.execl() cache_dir()/self_update which will:
            - remove worker packages except __machination__
            - remove core and __machination__ only if changed
            - add core package (if changed)
            - add worker packages
        """
        # Create a directory in which to store self update material
        sudir = os.path.join(context.cache_dir(), "selfupdate")
        try:
            os.mkdir(sudir)
        except OSError as e:
            if e.errno != errno.EEXIST:
                raise

        # Copy the self update script
        su_script_name = "machination-self-update.py"
        shutil.copy(os.path.join(context.bin_dir(), su_script_name), sudir)
        su_script = os.path.join(sudir, su_script_name)

        # Write installedVersion elements (current and desired)
        iv = etree.Element("iv")
        # Write the location of bundles into iv (at /iv/@bundleDir)
        iv.set("bundleDir", os.path.join(context.cache_dir(), "bundles"))
        wu[0].set("version", "desired")
        self.generated_iv.set("version", "current")
        iv.append(self.generated_iv)
        iv.append(wu[0])

        # Check to make sure we aren't being asked to downgrade any
        # packages.
        curver = {}
        nocando = []
        for b in self.generated_iv:
            name, version = self.get_version(b.get("id"), name_too=True)
            curver[name] = version
        curxpath = 'installedVersion[@version="current"]/machinationFetcherBundle'
        for b in iv.xpath(curxpath):
            name, version = self.get_version(b.get("id"), name_too=True)
            if name not in curver:
                # pkg remove
                continue
            if version < curver[name]:
                l.wmsg("Refusing to downgrade " + name)
                l.wmsg("desired-status asks for version {} " + "but {} is installed".format(version, curver[name]))
                # Can't remove b while we're iterating - remember it
                # for later.
                nocando.append(b)
        for b in nocando:
            name, version = self.get_version(b.get("id"), name_too=True)
            wu[0].remove(b)
            wu[0].add(etree.Element("machinationFetcherBundle", id="{}-{}".format(name, curver[name])))

        iv_file = os.path.join(sudir, "installed_version.xml")
        with open(iv_file, "w") as ivf:
            ivf.write(etree.tostring(iv, pretty_print=True).decode())

        # Hand over to the self update script
        os.execl(sys.executable, "machination-self-update", su_script, iv_file)