Linux installer project

Linux specific forum
Bitblazer
Enthusiast
Enthusiast
Posts: 736
Joined: Mon Apr 10, 2017 6:17 pm
Location: Germany
Contact:

Linux installer project

Post by Bitblazer »

The Goal: Achieving a friendly compatible linux installer which works with different distributions and makes life especially for beginners and new purebasic users a lot easier

The Steps:
a) find the version we are running on (distribution, architecture (32 or 64bit)
b) display the information we found and let the user confirm it (this is especially important for the inevitable bugfixing in cases we completely fail for some reason)
c) do distribution dependant additional package installations (apt-get, yum), better ask the user for confirmation as it MIGHT result in a lot data being downloaded. This can result in costs or problems for other software or people who use the connection too. In a family/community, one person could make the network unusable for others for quite a while. Don't simply assume that software exists - VERIFY it and trow errors or make fixing suggestions if it doesn exist or can't be located (no commandline apt-get or yum for example)

The first step is to create a linux binary which detects the version and shows all informations it can get. Let the user decide how detailed the information should be that they want to see. For experts a super detailed technical documentation helps to find problems, for beginners it just confuses them or makes them blindly ignore things and confirm stuff they dont understand "anyway", this could later lead to unwanted problems. As a neat side-effect this tool could prove a generally useful linux tool for others too. It could even lead to increase purebasic popularity as people might think "hey thats nice, how was it done? could i do that too?". Due to the nature of linux and this project, the linux binary MUST be a textmode tool. We can prettify the thing by adding a desktop UI on top. Maybe both in one "hybrid" binary which could be neat (its possible for windows, so maybe also for linux).

At the end of the installation, a few tips which depend on the distribution could be created in the installed binary folder. Including a linux link list for purebasic resources on the web because they exist but are widely hidden all over the internet.

CentOS
find the version : ls /etc/*release*
should show : /etc/os-release

the files content for version 7:

Code: Select all

NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
commandline package manager is "yum"


Kubuntu
uname -a

Code: Select all

Linux jc-VirtualBox 4.18.0-10-generic #11-Ubuntu SMP Thu Oct 11 15:13:55 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
/etc/os-release

Code: Select all

NAME="Ubuntu"
VERSION="18.10 (Cosmic Cuttlefish)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.10"
VERSION_ID="18.10"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=cosmic
UBUNTU_CODENAME=cosmic
Any comments? Opinions? People who want to help? Did i forget something or can something be done in a better way?
Bitblazer
Enthusiast
Enthusiast
Posts: 736
Joined: Mon Apr 10, 2017 6:17 pm
Location: Germany
Contact:

Re: Linux installer project

Post by Bitblazer »

Step 1 - the textmode tool consisting of 2 files, showinfo.pbi and "textmode.pb", developed and tested with ubuntu. Compile it into a binary "textmode" and execute it with the parameter "tell all" to get all informations. This output can be displayed by a GUI Version or parsed and used for an installer. An installer could use more specific parameters to gather just the information it needs instead of grabbing everything. This uses www.whatsmyip.org to get the machines public IP address for the first test. A final version should obviously not rely on that, but this was just done to get the project started.

Any comments on the parameters? I would prefer to replace the "tell" command with something which fits the linux "command world" more naturally.

"showinfo.pbi"

Code: Select all

#ShowInfo_Verbose             = $1
#ShowInfo_ConsoleInited       = $02
#ShowInfo_B                   = $04

#ShowInfo_LogfileName         = "showinfolog.txt"

#ShowInfo_GetIPService        = "www.whatsmyip.org"
;#ShowInfo_GetIPService        = "www.google.de"

#ShowInfoField_Name                   = 1
#ShowInfoField_Version                = 2
#ShowInfoField_ID                     = 3
#ShowInfoField_IDLike                 = 4
#ShowInfoField_PrettyName             = 5
#ShowInfoField_URL                    = 6
#ShowInfoField_CodeName               = 7
#ShowInfoField_UbuntuCodeName         = 8
#ShowInfoField_VersionID              = 9
#ShowInfoField_PackageManager         = 10
#ShowInfoField_PackageInstallFlags    = 11
; IDE Options = PureBasic 5.62 (Linux - x64)
; CursorPosition = 8
; EnableXP
File "textmode.pb"

Code: Select all

; textmode client to show all relevant linux system informations

EnableExplicit

; the basic textmode part of this idea: https://www.purebasic.fr/english/viewtopic.php?f=15&t=71646&sid=b83071c81bbfbda6034bb063b6a7c898

; find my public IP adress, the one that other computers see when i connect to them. This often depends on NAT

Define Settings.i, NetworkResult.i, Result.I
Define Parameters.i
Define IPV4.q, IPV6.q
Define LoopCounter.i
Define Message$, Parameter$
Global AppFlags.i
Global Dim SystemInfo.s(20)
Global IPV4$, IPV6$

XIncludeFile "showinfo.pbi"

; returns strings for the V4 and V6 IP adress of this machine

Procedure Add2Log(Message$)
  Define FileID.i, Result.i
  
  FileID = OpenFile(#PB_Any, #ShowInfo_LogfileName, #PB_File_Append | #PB_Unicode)
  
  If (FileID <> 0)
    Result = WriteStringN(FileID, Message$, #PB_Unicode)
    CloseFile(FileID)
    If (Result = 0)
      Debug "couldn't append '" + Message$ + "' to logfile"
    EndIf
  EndIf
  
EndProcedure

; return value is the amount of IP types i could find or negative if something failed if no IP at all can be found (for example - no network connection exists)

; 1 - got IPV4
;
; -1 - couldn't get IP
; -3 - failed to get memory to read the temporary file
; -4 - failed to read the temporary html file
; -5 - couldn't locate the correct html tag

Procedure.i GetMyIP(*IPV4, *IPV6)
  
  Define Result.i, FileID.i, FSize.i, ReturnValue.i
  Define Position1.i, Position2.i
  Define *Buffer
  Define MSG$, TempFileName$, SearchToken$
  Define HtmlFile$, IPAddress$
  
  ; preset the result values
  
  IPV4$ = ""
  IPV6$ = ""
  
  TempFileName$ = GetTemporaryDirectory() + "showinfo.htm"
  
  DeleteFile(TempFileName$)
  
  Result = ReceiveHTTPFile(#ShowInfo_GetIPService, TempFileName$)
  
  If (Result = 0)
    ProcedureReturn -1
  EndIf
  
  ReturnValue = 1
  
  ; now find my IP in the file
  
  FileID = ReadFile(#PB_Any, TempFileName$)
  
  If (FileID <> 0)
    FSize = FileSize(TempFileName$)
    
    If (FSize > 0)
      *Buffer = AllocateMemory(FSize)
      If (*Buffer = 0)
        CloseFile(FileID)
        ReturnValue = -3
      EndIf
      
      ReturnValue = 0
      
      Result = ReadData(FileID, *Buffer, FSize)
      If (Result = FSize)
        SearchToken$ = "<span id=" + Chr(34) + "ip" + Chr(34) + ">"
        HtmlFile$ = PeekS(*Buffer, FSize, #PB_Ascii)
        Position1 = FindString(HtmlFile$, SearchToken$)
        Position2 = FindString(HtmlFile$, "</span>")
        
        If ((Position1 <> 0) And (Position2 <> 0))
          Position1 + 14
          IPV4$ = Mid(HtmlFile$, Position1, (Position2 - Position1) -1)
          ReturnValue = 1
        Else
          ReturnValue = -5
        EndIf
        
      Else
        ReturnValue = -4
      EndIf
      
      FreeMemory(*Buffer)
      *Buffer = 0
    EndIf
    
    CloseFile(FileID)
    FileID = 0
  Else
    ReturnValue = -2
  EndIf
  
  ; cleanup
  DeleteFile(TempFileName$)
  
  ProcedureReturn ReturnValue
  
EndProcedure

Procedure ShowInfo_Init()
  AppFlags = #SHOWINFO_Verbose
  IPV4$ = ""
  IPV6$ = ""
EndProcedure

Procedure ShowInfo_Print(Message$)
  If ((AppFlags & #SHOWINFO_ConsoleInited) = 0)
    If (OpenConsole() = 0)
      End 999
    EndIf
    
    AppFlags = AppFlags | #SHOWINFO_ConsoleInited
  EndIf
  
  PrintN(Message$)
EndProcedure

Procedure GetOSRelease()
  
  Define FileID.i
  Define ThisLine$, Field$, FieldValue$
  
  FileID.i = ReadFile(#PB_Any, "/etc/os-release")
  
  If (FileID = 0)
    ProcedureReturn -1
  EndIf
  
  Add2Log("Content of os-release")
  While (Eof(FileID) = 0)
    ThisLine$ = ReadString(FileID)
    Add2Log(ThisLine$)
    Field$ = LCase(StringField(ThisLine$, 1, "="))
    FieldValue$ = ReplaceString(StringField(ThisLine$, 2, "="), Chr(34), "")
    Select Field$
      Case "name"
        SystemInfo(#ShowInfoField_Name) = FieldValue$
        If (FieldValue$ = "Ubuntu")
          SystemInfo(#ShowInfoField_PackageManager) = "apt-get"
        EndIf
        
      Case "version"
        SystemInfo(#ShowInfoField_Version) = FieldValue$
        
      Case "id"
        SystemInfo(#ShowInfoField_ID) = FieldValue$
        
      Case "id_like"
        SystemInfo(#ShowInfoField_IDLike) = FieldValue$
        
      Case "pretty_name"
        SystemInfo(#ShowInfoField_PrettyName) = FieldValue$
        
      Case "home_url"
        SystemInfo(#ShowInfoField_URL) = FieldValue$
        
      Case "version_id"
        SystemInfo(#ShowInfoField_VersionID) = FieldValue$
        
      Case "bug_report", "privacy_url", "home_url", "privacy_policy_url", "bug_report_url", "support_url"
      
      Case "version_codename"
        SystemInfo(#ShowInfoField_CodeName) = FieldValue$
        
      Case "ubuntu_codename"
        SystemInfo(#ShowInfoField_UbuntuCodeName) = FieldValue$
        
      Default
        If ((AppFlags & #ShowInfo_Verbose) = #ShowInfo_Verbose)
          Print("unhandled field '" + Field$ + "' with value '" + FieldValue$ + "'")
          Debug "unhandled field '" + Field$ + "' with value '" + FieldValue$ + "'"
        EndIf
    EndSelect
        
;    Debug "got " + Field$+ " with '" + FieldValue$ + "'"
  Wend
  
  Add2Log("Content of os-release ---------- end")
  CloseFile(FileID)
  
  ProcedureReturn 1
  
EndProcedure

DeleteFile(#ShowInfo_LogfileName)

ShowInfo_Init()

; ShowInfo_Print(Message$)

; If (Result > 0)
;   For LoopCounter = 1 To Result
;     Parameter$ = ProgramParameter(LoopCounter - 1)
;     Message$ = "Parameter " + Str(LoopCounter) + " is '" + Parameter$ + "'"
;     ShowInfo_Print(Message$)
;   Next
; EndIf

GetOSRelease()

NetworkResult = InitNetwork()

If (NetworkResult <> 0)
  Result = GetMyIP(@IPv4, @IPV6)
  
  Select Result
    Case 0
      ; we just don't output any info in this case
      
    Case 1
      
    Default
      
  EndSelect

EndIf

; get commandline parameters

Parameters = CountProgramParameters()

If (Parameters = 2)
  If (ProgramParameter(0) = "tell")
    Select ProgramParameter(1)
      Case "all" :
        ShowInfo_Print("Name = " + SystemInfo(#ShowInfoField_Name))
        ShowInfo_Print("Version = " + SystemInfo(#ShowInfoField_Version))
        ShowInfo_Print("ID = " + SystemInfo(#ShowInfoField_ID))
        ShowInfo_Print("ID Like = " + SystemInfo(#ShowInfoField_IDLike))
        ShowInfo_Print("PrettyName = " + SystemInfo(#ShowInfoField_PrettyName))
        ShowInfo_Print("URL = " + SystemInfo(#ShowInfoField_URL))
        ShowInfo_Print("Code Name = " + SystemInfo(#ShowInfoField_CodeName))
        ShowInfo_Print("Ubuntu Name = " + SystemInfo(#ShowInfoField_UbuntuCodeName))
        ShowInfo_Print("VersionID = " + SystemInfo(#ShowInfoField_VersionID))
        ShowInfo_Print("Package Manager = " + SystemInfo(#ShowInfoField_PackageManager))
        If (IPV4$ <> "")
          ShowInfo_Print("IPV4 = " + IPV4$)
        EndIf
        
        If (IPV6$ <> "")
          ShowInfo_Print("IPV6 = " + IPV6$)
        EndIf
        
      Case "ip" :
        If (IPV4$ <> "")
          ShowInfo_Print("IPV4 = " + IPV4$)
        EndIf
        
        If (IPV6$ <> "")
          ShowInfo_Print("IPV6 = " + IPV6$)
        EndIf
        
      Case "name" :
        ShowInfo_Print(SystemInfo(#ShowInfoField_Name))
        
      Case "version" :
        ShowInfo_Print(SystemInfo(#ShowInfoField_Version))
        
      Case "id" :
        ShowInfo_Print(SystemInfo(#ShowInfoField_ID))
        
      Case "idlike" :
        ShowInfo_Print(SystemInfo(#ShowInfoField_IDLike))
        
      Case "prettyname" :
        ShowInfo_Print(SystemInfo(#ShowInfoField_PrettyName))
        
      Case "url" :
        ShowInfo_Print(SystemInfo(#ShowInfoField_URL))
        
      Case "codename" :
        ShowInfo_Print(SystemInfo(#ShowInfoField_CodeName))
        
      Case "ubuntucodename" :
        ShowInfo_Print(SystemInfo(#ShowInfoField_UbuntuCodeName))
        
      Case "versionid" :
        ShowInfo_Print(SystemInfo(#ShowInfoField_VersionID))
        
      Case "packagemanager" :
        ShowInfo_Print(SystemInfo(#ShowInfoField_PackageManager))
        
      Default :
        ShowInfo_Print("unknown parameter '" + ProgramParameter(1) + "'")
    EndSelect
  EndIf
EndIf

; IDE Options = PureBasic 5.62 (Linux - x64)
; CursorPosition = 285
; FirstLine = 243
; Folding = -
; EnableXP
Bitblazer
Enthusiast
Enthusiast
Posts: 736
Joined: Mon Apr 10, 2017 6:17 pm
Location: Germany
Contact:

Re: Linux installer project

Post by Bitblazer »

Output from my own VM running the latest Kubuntu this morning

Code: Select all

Name = Ubuntu
Version = 18.10 (Cosmic Cuttlefish)
ID = ubuntu
ID Like = debian
PrettyName = Ubuntu 18.10
URL = https://www.ubuntu.com/
Code Name = cosmic
Ubuntu Name = cosmic
VersionID = 18.10
Package Manager = apt-get
IPV4 = 131.14.101.7
Bitblazer
Enthusiast
Enthusiast
Posts: 736
Joined: Mon Apr 10, 2017 6:17 pm
Location: Germany
Contact:

Re: Linux installer project

Post by Bitblazer »

I would like to add values for detecting the GUI next. So the tool knows which compiled GUI tool should work. Any hints how to reliably detect the running GUI would be appreciated :) gtk2, gtk3 and if possible plasma, gnome and all the others.
Bitblazer
Enthusiast
Enthusiast
Posts: 736
Joined: Mon Apr 10, 2017 6:17 pm
Location: Germany
Contact:

Re: Linux installer project

Post by Bitblazer »

The GUI display V 0.1 first implementation showing basic linux info the installer can use.
Image

Next steps - making it a more useful tool by changing it to a panel gadget where the current page is the first panel and seperate panels add memory, disk, network, gpu info etc. Once thats done, the installer work can begin and obviously support for other linux systems beside just ubuntu should be added.
Post Reply