Repositories

  • Themenstarter Themenstarter Bgag
  • Beginndatum Beginndatum
B

Bgag

Guten Abend!
Ich stehe mal wieder vor einem kleinen Problem. Ich sitze schon seit längerem an einer Klasse zur Verwaltung von Repositories. Einige Fuktionen stehen bereits ein Konzept ist ausgearbeitet. Zum besseren Verständnis gehe ich kurz auf das Konzept und den momentanen Stand ein.

Vorgesehene Funktionen:
  • *.csv-Datei auslesen, die die Repository-Server enthält
  • von diesen Servern die control.csv mit den Package-Informationen auslesen
  • die Package-Informationen zerlegen und als Array zurückgeben
  • einen Download auf den eigenen Server von ungeschützten Packages ermöglichen
  • einen Download auf den eigenen Server von geschützten Packages ermöglichen
  • Package (Tarball) in temporäres Verzeichnis entpacken
  • install.php ausführen danach temporären Ordner löschen
  • uninstall_packagename.php ausführen danach Datei löschen

Ich denke das gibt schon einen guten Einblick. Wir haben also nur drei Dateien und zwei Ordner. Es gibt die Klasse Repository.php, den Ordner Temp und die Datei repos.csv, die die Repository-Server enthält auf dem Client. Auf jedem Repository-Server liegt eine Datei control.csv, die die Package-Informationen enthält. Soweit ist denke ich alles klar. Wo liegen nun noch meine Probleme?

Zum einen Funktioniert zwar die Methode untar(), die die Packages (Tarballs) entpackt, allerdings werden Bilder nicht wieder richtig hergestellt. Lustigerweise funktioniert dies bei *.ico-Dateien, aber eben bei so ziemlich allen anderen image-Dateien nicht. Andere nicht voll textbasierte Formate (*.doc / *.pdf / *.mp3) werden auch nicht richtig entpackt, aber das war ja zu erwarten und macht auch nichts, da ja so oder so nur Image-, *.css-, *.html und *.php-Dateien entpackt werden müssen. Meine Frge wie kann ich es jetzt anstellen, dass auch image-Dateien korrekt entpackt werden. Die Methode habe ich unten angehängt.

Zum anderen habe ich ein Problem mit dem Download eines Packages auf den Client-Server. Wie kann ich einen Download gestalten ohne dass eine Frage an den Client gestellt wird, ob diese Datei wirklich heruntergeladen werden soll. Zur verfügung stehen mir unter anderem eine FTP- als auch eine Http-Klasse.

Wäre euch echt sehr dankbar, wenn ihr mir bei meinen Problemen helfen könntet.
MfG, Andy

PHP:
	/**
	* untar() - Unpacks a tar-archiv
	* 
	* @access public
	* @param Str $tar	path to tar-archiv
	* @param Str $to	relativ path
	* @return Boolean
	*/
	public function untar($tar, $to)
	{
		// does the tar-archiv exists
		if (file_exists($tar)) 
		{
			$to = realpath($to);

			if(substr($to, -1) != '/')
			{
				$to .= '/';
			}

			if(false == is_dir($to))
			{
				// create relativ dir
				mkdir($to, 0777);
			}

			// open tarball
			$tar = fopen($tar, 'r');

			// do until reaching end of tar-archiv
			while (!feof($tar))
			{
				// read info-block
				$info = fread($tar, 512);
				$name = trim(substr($info, 0, 100));
				$size = octdec(trim(substr($info, 124, 12)));

				// if $name is a dir create it
				if($size == 0 && false == is_dir($name))
				{
					mkdir($to . $name, 0777);
				}

				else
				{
					// read content-block
					$content = '';
					for ($rec = 0; $rec < $size; $rec+=512)
					{
						$content .= trim(fread($tar, 512));
					}

					// write content into file
					$file = fopen($to . $name, 'a');
					fwrite($file, $content);
					fclose($file);
				}
			}

			// close tar-file
			fclose($tar);
		}

		else
		{
			throw new Exception('Tarball does not exist.');
		}
	}

PS: Hoffe, dass das die neuste Version ist. Sitze leider gerade mit meinem eee-PC in einem Cafè. :) Zudem hoffe ich, dass sie übersichtlich und verständlich genug ist.

//EDIT: Kurze Anmerkung noch zur untar()-Methode. Ich greife absichtlich auf die Datei-Informationen im ersten Teil des erten Blocks (Bit 1 bis 257) einer Datei zu und nicht auf die hinter USTAR. USTAR steht nämlich nur bei neueren Archiven zur Verfügung die anderen Informationen allerdings immer.

//EDIT: Hervorangende Informationen zu dem Thema Tarballs findet man übrigens im englischen Wikipedia.
 
Zuletzt bearbeitet von einem Moderator:
Lass die chr()-Funktionen weg, die sind sinnlos, da substr() bereits eine Zeichenkette zurück liefert.
 
chr() erfüllt doch nicht die gleiche Funktion wie substr(). chr() dekodiert ein ASCII-Zeichen, substr() liefert einen Teilstring zurück. Schau nachher mal ob das überhaupt noch die aktuelle Version ist.
MfG, Andy

//EDIT: Es tut mir wirklich leid. Die untar()-Methode war leider absolut veraltet. Denke aber, dass diese Methode viel besser zu verstehen ist. zudem ist sie viel übersichtlicher und überflüssige Daten werden garnicht erst ausgelesen. Bei Fragen zur Methode hilft, wie gesagt das englische Wikipedia.
PHP:
	/**
	* untar() - Unpacks a tar-archiv
	* 
	* @access public
	* @param Str $tar	path to tar-archiv
	* @param Str $to	relativ path
	* @return Boolean
	*/
	public function untar($tar, $to)
	{
		// does the tar-archiv exists
		if (file_exists($tar)) 
		{
			$to = realpath($to);

			if(substr($to, -1) != '/')
			{
				$to .= '/';
			}

			if(false == is_dir($to))
			{
				// create relativ dir
				mkdir($to, 0777);
			}

			// open tarball
			$tar = fopen($tar, 'r');

			// do until reaching end of tar-archiv
			while (!feof($tar))
			{
				// read info-block
				$info = fread($tar, 512);
				$name = trim(substr($info, 0, 100));
				$size = octdec(trim(substr($info, 124, 12)));

				// if $name is a dir create it
				if($size == 0 && false == is_dir($name))
				{
					mkdir($to . $name, 0777);
				}

				else
				{
					// read content-block
					$content = '';
					for ($rec = 0; $rec < $size; $rec+=512)
					{
						$content .= trim(fread($tar, 512));
					}

					// write content into file
					$file = fopen($to . $name, 'a');
					fwrite($file, $content);
					fclose($file);
				}
			}

			// close tar-file
			fclose($tar);
		}

		else
		{
			throw new Exception('Tarball does not exist.');
		}
	}
 
Zuletzt bearbeitet von einem Moderator:
Oh guter Einwand. Muss mir nochmal genau überlegen was ich mache. Auf jeden Fall sollte ich den Datei-Typ anhand des Link Indikators überprüfen. Wobei ich mir da nochmal genau überlegen muss, welche Typen man zusammenfassen kann (Rückgabe 1-3 in der Tabelle). Zudem ist diese Zeile
PHP:
if($size == 0 && false == is_dir($name))
tatsächlich vollkommender Schwachsinn. Dort werden leere Dateien plötzlich wie Verzeichnisse behandelt. AUA! Da sollte ich dann vielleicht auch einfach auf Link-Indikator prüfen. Kann mir vielleicht dann noch jemand mit dem Image-File-Problem in der untar()-Methode und dem Download-Problem in der Repository-Klasse helfen?
MfG, Andy
 
Ich hab jetzt mal eine Frage die dies nicht beantwortet, aber einen anderen Lösungsweg verwendet....
Für gewöhnlich sind aktiv laufende System ja Linux oder Unix Server.
Wie wäre es Aufgaben wie entpacken via linux befehl auszuführen, ist zumindest um einiges schneller.

Oder:
Wenn Betriebssystem = linunx || Unix
dann exec(tar ...);
sonst verwende die klasse....
 
Guten Morgen!
Ich denke es ist mal wieder an der Zeit an dieser Stelle weiter zu arbeiten. Die Idee war ja Module oder AddOns von einem zentralen Repository-Server installieren zu können, allerdings hab ich festgestellt, dass dies ein relativ scheres unterfangen ist. Daher habe ich mich nun entschieden diese Module oder AddOns als Pakete zum Download anzubieten, damit der User diese downloaden und dann über ein Adminpanel hochladen und installieren kann.

Das Problem ist nun, dass ich nicht weiß, wie ich soetwas am besten strukturiere. An dieser Stelle hoffe ich auf eure Hilfe. Zu klären wären für mich die folgenden Fragen:
  1. Wie sollten die Packages aufgebaut sein?
  2. Wie könnte eine Installations-Datei arbeiten?
  3. Wie sollte die Deinstallation organisiert werden?
  4. Wie könnte die Fehlerbehandlung in der Installations- bzw. Deinstallations-Datei aussehen?
  5. Wie könnte eine passende Ordnerstruktur aussehen?
  6. Wie kann ich dafür sorgen, dass nur eine Version eines Packages installiert ist?
Zu einigen dieser Fragen habe ich mir bereits Gedanken gemacht.

So denke ich weiterhin, dass ich Tarballs als Packages verwenden sollte. Diese können nach dem Upload in einem Temporären Ordner abgelegt und entpackt werden. An der entsprechenden Methode habe ich ja bereits gearbeitet. Nach dem entpacken könnte eine weitere Methode die in jedem Package enthaltene install.php aufrufen und die Ausgabe des Scrippts puffern. Die install.php verschiebt alle wichtigen Dateien in einem zum Package gleichnamigen Ordner in den Ordner Module. Funktioniert dies ist alles gut. Tritt allerdings bei der Installation ein Fehler auf, sollen sowohl die temporären Dateien, als auch der neue Ordner und seine Inhalte im Ordner Module gelöscht werden. Daraufhin kann dann eine simple Anzeige "Installation von {$package} fehlgeschlagen." erscheinen.

Was haltet ihr von diesem Ansatz und habt ihr vielleicht Antworten auf meine Fragen? Ich bin wie immer für alles offen.
MfG, Andy
 
Zurück