summaryrefslogblamecommitdiffstats
path: root/modules-available/statistics/pages/hints.inc.php
blob: bfb28c24f4d2562be918f091c92be69d74ec2f55 (plain) (tree)
1
2
3
4
5
6
7
8






                                             
                                                



                                         



                                                           
                                           
                                               
                                          
                                             
                                            

         
                                                                             











                                                                              



                                                                   
                                                              

                                                                


                                                                       
                                                                            




                                                               
                                              
                                                                                                           

                                               

                                                                          


                                                                                                                      
                         


                                                                                        
                                                                                            
                                       
                 

                                 
                                                           


                                                                            



                                                             
                                                           

                                                                 


                                                                       
                                                                            

                                                     






                                                    
                                              

                                                                                       


                                                                                                                          

                                                                                                            
                                         
                                                                                            

                                       

                                 
                                                           


                                                                                 



                                                                 
                                                            
         

                                   
                                                          


                                                                       
                                                                            

                                                 
                                                                                    
                                                                   
                                              
                                               

                                                                                         
                                                                                            


                                       
                                                          


                                                                       
                                                                            

                                                 
                                                                                      

                                                                   
                                              

                                                                                                       
                                               


                                                                                         
                                                                                            

                                       

                                                 

                                                           





                                                       






                                                                       
                                                                            

                                                 
                                              





                                                                         
                                                                                            



                                       
                                                           


                                                                          
















                                                                                 



                                                                                            





                                                                           
 
<?php

class SubPage
{

	public static function doPreprocess()
	{
		User::assertPermission('hints');
	}

	public static function doRender()
	{
		$locs = User::getAllowedLocations('hints');
		if (in_array(0, $locs)) {
			$locs = [];
		}
		self::showLegacyCpu($locs);
		self::showMemoryUpgrade($locs);
		self::showSlowNics($locs);
		self::showUnusedSpace($locs);
		self::showMemorySlow($locs);
	}

	private static function isNonClientRunmode(string $machineUuid): bool
	{
		static $cache = null;
		if ($cache === null) {
			if (!Module::isAvailable('runmode')) {
				$cache = [];
			} else {
				$cache = RunMode::getAllClients(false, false);
			}
		}
		return isset($cache[$machineUuid]);
	}

	/**
	 * Machines that have less than 8GB of RAM. Highlight those
	 * that still have free memory slots.
	 */
	private static function showMemoryUpgrade(array $locs)
	{
		$q = new HardwareQuery(HardwareInfo::MAINBOARD);
		if (!empty($locs)) {
			$q->addMachineWhere('locationid', 'IN', $locs);
		}
		$q->addMachineWhere('lastseen', '>', strtotime('-60 days'));
		$q->addLocalColumn('Memory Slot Occupied');
		$q->addGlobalColumn('Memory Slot Count');
		$q->addGlobalColumn('Memory Maximum Capacity');
		$q->addMachineColumn('clientip');
		$q->addMachineColumn('hostname');
		$q->addMachineColumn('state');
		$q->addLocalColumn('Memory Installed Capacity')->addCondition('<', 8 * 1024 * 1024 * 1024);
		$list = [];
		foreach ($q->query() as $row) {
			if (self::isNonClientRunmode($row['machineuuid']))
				continue;
			if (HardwareParser::convertSize($row['Memory Installed Capacity'], 'M', false)
					>= HardwareParser::convertSize($row['Memory Maximum Capacity'], 'M', false)) {
				$row['size_class'] = 'danger';
			}
			if ($row['Memory Slot Occupied'] >= $row['Memory Slot Count']) {
				$row['count_class'] = 'warning';
			}
			$row['icon'] = StatisticsStyling::machineStateToIcon($row['state']);
			$list[] = $row;
		}
		if (empty($list))
			return;
		ArrayUtil::sortByColumn($list, 'hostname');
		Render::addTemplate('hints-ram-upgrade', ['list' => $list]);
	}

	/**
	 * Show machines where RAM modules are running slower
	 * than their design speed.
	 */
	private static function showMemorySlow(array $locs)
	{
		$q = new HardwareQuery(HardwareInfo::RAM_MODULE);
		if (!empty($locs)) {
			$q->addMachineWhere('locationid', 'IN', $locs);
		}
		$q->addMachineWhere('lastseen', '>', strtotime('-60 days'));
		//$q->addLocalColumn('Locator');
		//$q->addLocalColumn('Bank Locator');
		$q->addGlobalColumn('Form Factor');
		$q->addGlobalColumn('Type');
		$q->addGlobalColumn('Size');
		$q->addGlobalColumn('Manufacturer');
		$q->addLocalColumn('Serial Number');
		$q->addMachineColumn('clientip');
		$q->addMachineColumn('hostname');
		$q->addMachineColumn('state');
		$col = $q->addGlobalColumn('Speed');
		$col->addCondition('>', $q->addLocalColumn('Configured Memory Speed'));
		$list = [];
		foreach ($q->query(['machineuuid', 'Size', 'Manufacturer', 'Speed', 'Configured Memory Speed']) as $row) {
			// Sometimes configured speed reports as 2666 while rated speed is 2667
			// Cast as these have a MT/s suffic, triggering a PHP notice about malformed numbers
			if ((int)$row['Configured Memory Speed'] + 33 >= (int)$row['Speed'])
				continue;
			$row['icon'] = StatisticsStyling::machineStateToIcon($row['state']);
			$list[] = $row;
		}
		if (empty($list))
			return;
		ArrayUtil::sortByColumn($list, 'hostname');
		Render::addTemplate('hints-ram-underclocked', ['list' => $list]);
	}

	/**
	 * Show machines that have unpartitioned space available,
	 * and no ID44 or ID45.
	 */
	private static function showUnusedSpace(array $locs)
	{
		$id44 = $id45 = [];
		// ID44
		$q = new HardwareQuery(HardwareInfo::HDD);
		if (!empty($locs)) {
			$q->addMachineWhere('locationid', 'IN', $locs);
		}
		$q->addMachineWhere('lastseen', '>', strtotime('-60 days'));
		$q->addMachineColumn('clientip');
		$q->addMachineColumn('hostname');
		$q->addLocalColumn('unused')->addCondition('>', 2000000000); // 2 GB
		$q->addMachineWhere('id44mb', '<', 20000); // 20 GB
		$q->addMachineColumn('state');
		foreach ($q->query() as $row) {
			$row['unused_s'] = Util::readableFileSize($row['unused']);
			$row['id44mb_s'] = Util::readableFileSize($row['id44mb'], -1, 2);
			$row['icon'] = StatisticsStyling::machineStateToIcon($row['state']);
			$id44[] = $row;
		}
		// ID45
		$q = new HardwareQuery(HardwareInfo::HDD);
		if (!empty($locs)) {
			$q->addMachineWhere('locationid', 'IN', $locs);
		}
		$q->addMachineWhere('lastseen', '>', strtotime('-60 days'));
		$q->addMachineColumn('clientip');
		$q->addMachineColumn('hostname');
		$q->addLocalColumn('unused')->addCondition('>', 50000000000); // 50 GB
		$q->addMachineWhere('id44mb', '>', 20000); // 20 GB
		$q->addMachineWhere('id45mb', '<', 20000); // 20 GB
		$q->addMachineColumn('state');
		// Only suggest SSD based systems, caching on spinning rust is usually slower than GBit
		$q->addGlobalColumn('rotation_rate')->addCondition('=', 0);
		foreach ($q->query() as $row) {
			$row['unused_s'] = Util::readableFileSize($row['unused']);
			$row['id44mb_s'] = Util::readableFileSize($row['id44mb'], -1, 2);
			$row['id45mb_s'] = Util::readableFileSize($row['id45mb'], -1, 2);
			$row['icon'] = StatisticsStyling::machineStateToIcon($row['state']);
			$id45[] = $row;
		}
		if (empty($id44) && empty($id45))
			return;
		ArrayUtil::sortByColumn($id44, 'hostname');
		ArrayUtil::sortByColumn($id45, 'hostname');
		Render::addTemplate('hints-hdd-grow', [
			'id44' => $id44,
			'id45' => $id45,
		]);
	}

	private static function showSlowNics(array $locs)
	{
		$list = [];
		$q = new HardwareQuery(HardwareInfo::MAINBOARD);
		if (!empty($locs)) {
			$q->addMachineWhere('locationid', 'IN', $locs);
		}
		$q->addMachineWhere('lastseen', '>', strtotime('-60 days'));
		$q->addMachineColumn('clientip');
		$q->addMachineColumn('hostname');
		$q->addMachineColumn('state');
		$q->addLocalColumn('nic-speed')->addCondition('<', 1000);
		$q->addLocalColumn('nic-duplex');
		foreach ($q->query() as $row) {
			if ($row['nic-speed'] == 0) {
				$row['nic-speed'] = '???';
			}
			$row['icon'] = StatisticsStyling::machineStateToIcon($row['state']);
			$list[] = $row;
		}
		if (empty($list))
			return;
		ArrayUtil::sortByColumn($list, 'hostname');
		Render::addTemplate('hints-nic-speed', ['list' => $list]);
	}

	/**
	 * Show machines that have a CPU that is only supported by VMware 12.5.x,
	 * but not newer versions.
	 */
	private static function showLegacyCpu(array $locs)
	{
		$list = [];
		$q = new HardwareQuery(HardwareInfo::CPU);
		if (!empty($locs)) {
			$q->addMachineWhere('locationid', 'IN', $locs);
		}
		$q->addMachineWhere('lastseen', '>', strtotime('-60 days'));
		$q->addMachineColumn('clientip');
		$q->addMachineColumn('hostname');
		$q->addMachineColumn('state');
		$q->addMachineColumn('cpumodel');
		$q->addGlobalColumn('vmx-legacy')->addCondition('<>', 0);
		foreach ($q->query() as $row) {
			$row['icon'] = StatisticsStyling::machineStateToIcon($row['state']);
			$list[] = $row;
		}
		if (empty($list))
			return;
		ArrayUtil::sortByColumn($list, 'hostname');
		Render::addTemplate('hints-cpu-legacy', ['list' => $list]);
	}

}