<commit_before># Copyright (c) 2011 rPath, Inc.
# Assimilates different families of non-managed systems into an rBuilder
# used by rmake_plugins/assimilator_plugin.py

import exceptions
import os
import re
import subprocess
import hashlib
import shutil
import tarfile
from conary.lib import util
from conary.conaryclient import ConaryClient
from conary.conarycfg import ConaryConfiguration
from conary.versions import Label
from conary.deps import deps
from rpath_repeater.codes import Codes as C

class LinuxAssimilator(object):
    """
    Assimiles a Linux system
    
    usage:
        sshConn = utils.SshConnection(...)
        asim = LinuxAssimilator(sshConnector=sshConn, caCert=str, 
            zoneAddresses=rus_hosts_with_ports)
        asim.assimilate()
    """

    def __init__(self, sshConnector=None, zoneAddresses=None, 
        caCert=None, status=None, platformLabels=None, 
        installTrove=None, projectLabel=None, eventUuid=-1):

        self._status               = status
        self.ssh                   = sshConnector
        self.platformLabels        = platformLabels
        self.osFamily, self.flavor = self._discoverFamilyAndFlavor()
        self.zoneAddresses         = zoneAddresses
        self.caCert                = caCert
        self.eventUuid             = eventUuid
        self.installTrove          = installTrove
        self.projectLabel          = projectLabel

        self.builder = LinuxAssimilatorBuilder(
            osFamily       = self.osFamily,
            caCert         = caCert,
            flavor         = self.flavor,
            status         = self.status,
            platformLabels = platformLabels
        )
        self.payload       = self._makePayload()

    def status(self, code, msg):
       '''Share a status message'''
       if self._status:
           self._status(code, msg)

    def _makePayload(self):
        '''what tarball to deploy? stubbed out for easier mock testing'''
        return self.builder.getAssimilator()

    def _discoverFamilyAndFlavor(self):
        '''what kind of Linux OS is this?'''
        self.status(C.MSG_GENERIC, 'detecting flavor')
        rc, output = self.ssh.execCommand('uname -a')
        flavor = 'x86'
        if output.find("x86_64") != -1:
            flavor = 'x86_64'
        self.status(C.MSG_GENERIC, 'detecting release')
        rc, output = self.ssh.execCommand('cat /etc/redhat-release')
        if rc == 0:
            if output.find("Red Hat") != -1:
                return (self._versionFromRedHatRelease(output), flavor)
            else:
                return (self._versionFromCentOSRelease(output), flavor)
        else:
            rc, output = self.ssh.execCommand('cat /etc/SuSE-release')
            if rc == 0:
                return (self._versionFromSuseRelease(output), flavor)
            else:
                raise Exception("unable to detect OS family")

    def _versionFromRedHatRelease(self, output):
        '''Parse RHEL version from /etc/redhat-release data'''
        matches = re.findall('\d+', output.split("\n")[0])
        return ('RHEL', matches[0])

    def _versionFromCentOSRelease(self, output):
        '''Parse CentOS version from /etc/redhat-release data'''
        matches = re.findall('\d+', output.split("\n")[0])
        return ('CentOS', matches[0])

    def _versionFromSuseRelease(self, output):
        '''Parse SuSE version from /etc/SuSE-release data'''
        matches = re.findall('\d+', output.split("\n")[0])
        return ('SLES', matches[0])
        
    def _commands(self):
        '''
        Once an assimilation payload has been deployed on a system
        we have to run some commands to take it the rest of the
        way with registration.  This is likely not family specific
        but it might be, if it IS family specific the preferred way
        of handling it is a different bootstrap.sh in the payload.
        '''
        commands = []
        addrs = " ".join(self.zoneAddresses)
        commands.append("cd /; tar -xf /tmp/rpath_assimilator.tar")
        script = "/usr/conary/bin/python /usr/share/bin/rpath_bootstrap.py"
        commands.append("%s %s %s %s %s" % (script, self.eventUuid, self.projectLabel, self.installTrove, addrs))
        return commands

    def runCmd(self, cmd):
        ''' 
        Run command via SSH, logging into buffer
        '''
        output = "\n%s\n" % cmd<commit_msg>Quote install trove properly<commit_after># Copyright (c) 2011 rPath, Inc.
# Assimilates different families of non-managed systems into an rBuilder
# used by rmake_plugins/assimilator_plugin.py

import exceptions
import os
import re
import subprocess
import hashlib
import shutil
import tarfile
from conary.lib import util
from conary.conaryclient import ConaryClient
from conary.conarycfg import ConaryConfiguration
from conary.versions import Label
from conary.deps import deps
from rpath_repeater.codes import Codes as C

class LinuxAssimilator(object):
    """
    Assimiles a Linux system
    
    usage:
        sshConn = utils.SshConnection(...)
        asim = LinuxAssimilator(sshConnector=sshConn, caCert=str, 
            zoneAddresses=rus_hosts_with_ports)
        asim.assimilate()
    """

    def __init__(self, sshConnector=None, zoneAddresses=None, 
        caCert=None, status=None, platformLabels=None, 
        installTrove=None, projectLabel=None, eventUuid=-1):

        self._status               = status
        self.ssh                   = sshConnector
        self.platformLabels        = platformLabels
        self.osFamily, self.flavor = self._discoverFamilyAndFlavor()
        self.zoneAddresses         = zoneAddresses
        self.caCert                = caCert
        self.eventUuid             = eventUuid
        self.installTrove          = installTrove
        self.projectLabel          = projectLabel

        self.builder = LinuxAssimilatorBuilder(
            osFamily       = self.osFamily,
            caCert         = caCert,
            flavor         = self.flavor,
            status         = self.status,
            platformLabels = platformLabels
        )
        self.payload       = self._makePayload()

    def status(self, code, msg):
       '''Share a status message'''
       if self._status:
           self._status(code, msg)

    def _makePayload(self):
        '''what tarball to deploy? stubbed out for easier mock testing'''
        return self.builder.getAssimilator()

    def _discoverFamilyAndFlavor(self):
        '''what kind of Linux OS is this?'''
        self.status(C.MSG_GENERIC, 'detecting flavor')
        rc, output = self.ssh.execCommand('uname -a')
        flavor = 'x86'
        if output.find("x86_64") != -1:
            flavor = 'x86_64'
        self.status(C.MSG_GENERIC, 'detecting release')
        rc, output = self.ssh.execCommand('cat /etc/redhat-release')
        if rc == 0:
            if output.find("Red Hat") != -1:
                return (self._versionFromRedHatRelease(output), flavor)
            else:
                return (self._versionFromCentOSRelease(output), flavor)
        else:
            rc, output = self.ssh.execCommand('cat /etc/SuSE-release')
            if rc == 0:
                return (self._versionFromSuseRelease(output), flavor)
            else:
                raise Exception("unable to detect OS family")

    def _versionFromRedHatRelease(self, output):
        '''Parse RHEL version from /etc/redhat-release data'''
        matches = re.findall('\d+', output.split("\n")[0])
        return ('RHEL', matches[0])

    def _versionFromCentOSRelease(self, output):
        '''Parse CentOS version from /etc/redhat-release data'''
        matches = re.findall('\d+', output.split("\n")[0])
        return ('CentOS', matches[0])

    def _versionFromSuseRelease(self, output):
        '''Parse SuSE version from /etc/SuSE-release data'''
        matches = re.findall('\d+', output.split("\n")[0])
        return ('SLES', matches[0])
        
    def _commands(self):
        '''
        Once an assimilation payload has been deployed on a system
        we have to run some commands to take it the rest of the
        way with registration.  This is likely not family specific
        but it might be, if it IS family specific the preferred way
        of handling it is a different bootstrap.sh in the payload.
        '''
        commands = []
        addrs = " ".join(self.zoneAddresses)
        commands.append("cd /; tar -xf /tmp/rpath_assimilator.tar")
        script = "/usr/conary/bin/python /usr/share/bin/rpath_bootstrap.py"
        commands.append("%s %s %s '%s' %s" % (script, self.eventUuid,
            self.projectLabel, self.installTrove, addrs))
        return commands

    def runCmd(self, cmd):
        ''' 
        Run command via SSH, logging into buffer
        '''
        output = "\n%s\n" % cmd
{'fraction_non_alphanumeric': 0.1011172553887823, 'fraction_numerical': 0.005642703983749013, 'mean_word_length': 2.2155297532656024, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '652513', 'n_tokens_mistral': 2553, 'n_tokens_neox': 2485, 'n_words': 680}