Is it possible to do OTA update for the ESP32 using Arduino IDE 2.0.x via Ethernet instead of WiFi?

Great well i already have succeeded at that.
Start out by uploading this code (please don't mind the commented out bits)


//#define W5500_RST_PORT   21     // i don't have that connected, but i have W5500 RST to ESP32 RST
//#define ETHERNET_LARGE_BUFFERS  // optional have to verify how much buffers will be used
#define W5500_CS 5 
#define SPI_FRQ 32000000 // better than the 1 or 4MHz default

#include <WiFi.h>
#include <WebServer.h>
#include <ArduinoOTA.h>
#include <StreamString.h>
#include <SPI.h>
#include <EthernetWebServer.h>
#include "Ethernet_Generic.h"
//#include <EthernetUdp.h> // not needed yet

const char* ssid     = "XXX";
const char* password = "xxxxxxxx";
const char* update_path = "/firmware";

static const char pageheader[] PROGMEM = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
static const char htmlhead[] PROGMEM = "<html><head><title>HttpUpdater</title><meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" ></head>";
static const char bodystyle[] PROGMEM = "<body style=\"color: dimgray; background-color: palegoldenrod; font-size: 12pt; font-family: sans-serif;\">";
static const char htmlclose[] PROGMEM = "</body></html>";


EthernetWebServer ethernetServer(80);
WebServer wifiServer(80);

const int led = 2;

void handleEthernetRoot() {
  ethernetServer.send(200, "text/plain", "Hello from ESP32 Ethernet!");
  //ethernetServer.send(200, "text/plain", "Hello from ESP32 Ethernet!, The upload worked !!");
}

void handleWiFiRoot() {
  wifiServer.send(200, "text/plain", "Hello from ESP32 WiFi!");
}

void setup() {
  Serial.begin(115200);
  delay(100);
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  //OTAUpdateSetup();

  SPI.setFrequency(SPI_FRQ);

  Ethernet.init (W5500_CS);
  // start the ethernet connection and the server:
  // Use DHCP dynamic IP
  byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x01}; 
  //uint16_t index = millis() % NUMBER_OF_MAC;
  // Use Static IP
  //IPAddress ip(192, 168, 2, 222);
  //Ethernet.begin(mac, ip);
  Ethernet.begin(mac);

  Serial.println("Currently Used SPI pinout:");
  Serial.print("MOSI:");
  Serial.println(MOSI);
  Serial.print("MISO:");
  Serial.println(MISO);
  Serial.print("SCK:");
  Serial.println(SCK);
  Serial.print("CS/SS:");
  Serial.println(W5500_CS);

  ethernetServer.on("/", handleEthernetRoot);
  ethernetServer.on(update_path, HTTP_GET, handleUpdate);
  ethernetServer.on(update_path, HTTP_POST, handlePostUpdate, handleFileUpload);
  ethernetServer.begin();

  Serial.print("HTTP EthernetWebServer is @ IP : ");
  Serial.println(Ethernet.localIP());

  wifiServer.on("/", handleWiFiRoot);
  wifiServer.begin();

  Serial.print("HTTP WiFiWebServer is @ IP : ");
  Serial.println(WiFi.localIP());
}

void loop() {
  //ArduinoOTA.handle();
  ethernetServer.handleClient();
  wifiServer.handleClient();
}


//----------------------------------------- Firmware Update Pages -----------------------------------------------------

void handleUpdate() {

  if (!ethernetServer.authenticate("admin", "password"))
    return ethernetServer.requestAuthentication();
  String s = "";
  s += FPSTR(pageheader);
  s += FPSTR(htmlhead);
  s += FPSTR(bodystyle);
  s += "<h1>OTA Firmware Update</h1>";

  s += "<pre><form method='post' action='' enctype='multipart/form-data'>";
  s += "<input type='file' name='update'>";
  s += "           <input type='submit' value='  Update  '></form></pre>";
  s += FPSTR(htmlclose);
  ethernetServer.send(200, "text/html", s);
}


void handlePostUpdate() {
  if (!ethernetServer.authenticate("admin", "password"))
    return ethernetServer.requestAuthentication();
  if (Update.hasError()) {
    StreamString str;
    Update.printError(str);
    str;
    String s = "";
    s += FPSTR(pageheader);
    s += FPSTR(htmlhead);
    s += FPSTR(bodystyle);
    s += "<h1>Update Error </h1>";
    s += str;
    s += FPSTR(htmlclose);
    ethernetServer.send(200, "text / html", s);
  }
  else {
    String s = "";
    s += FPSTR(pageheader);
    s += FPSTR(htmlhead);
    s += FPSTR(bodystyle);
    s += "<META http-equiv='refresh' content='30;URL=/'>Update Success ! Rebooting...\n";
    s += (htmlclose);
    //ethernetServer.client().setNoDelay(true);
    ethernetServer.send(200, "text / html", s);
    delay(1000);
    ethernetServer.client().stop();
    ESP.restart();
  }
}

void handleFileUpload() {
  if (!ethernetServer.authenticate("admin", "password"))
    return ethernetServer.requestAuthentication();
  ethernetHTTPUpload& upload = ethernetServer.upload();
  String updateerror = "";
  if (upload.status == UPLOAD_FILE_START) {
    //EthernetUDP::stop();
    uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
    if (!Update.begin(maxSketchSpace)) { //start with max available size
      StreamString str;
      Update.printError(str);
      updateerror = str;
    }
  }
  else if (upload.status == UPLOAD_FILE_WRITE) {
    if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
      StreamString str;
      Update.printError(str);
      updateerror = str;
    }
  }
  else if (upload.status == UPLOAD_FILE_END) {
    if (Update.end(true)) { //true to set the size to the current progress
      StreamString str;
      Update.printError(str);
      updateerror = str;
    }
    else if (upload.status == UPLOAD_FILE_ABORTED) {
      Update.end();
    }
    yield();
  }
}

//-------------------------------------------- OTA Uploader Functions ---------------------------------------


/*void OTAUpdateSetup() {

  ArduinoOTA.setHostname("update");


  ArduinoOTA.setPassword("yes");

  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {

    }
    else { // U_SPIFFS
      type = "filesystem";
      //if (spiffsmounted) {
        //SPIFFS.end();
        //spiffsmounted = false;
      //}
    }

    // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
    //  Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {
    //if (!spiffsmounted) spiffsmounted = SPIFFS.begin();
    delay(1000);
    // Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    //  Serial.printf("Progress: % u % % \r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    //Serial.printf("Error[ % u]: ", error);
    if (error == OTA_AUTH_ERROR) {
      //  Serial.println("Auth Failed");
    }
    else if (error == OTA_BEGIN_ERROR) {
      //Serial.println("Begin Failed");
    }
    else if (error == OTA_CONNECT_ERROR) {
      //Serial.println("Connect Failed");
    }
    else if (error == OTA_RECEIVE_ERROR) {
      //Serial.println("Receive Failed");
    } else if (error == OTA_END_ERROR) {
      //Serial.println("End Failed");
    }
  });
  ArduinoOTA.begin();
}*/

Navigate to the ethernet & wifi IP's to verify it works as before.
Now change the comments here

void handleEthernetRoot() {
  //ethernetServer.send(200, "text/plain", "Hello from ESP32 Ethernet!");
  ethernetServer.send(200, "text/plain", "Hello from ESP32 Ethernet!, The upload worked !!");
}

and do 'Sketch->Export Compiled Binary'

Now go to the ethernet IP + '/firmware'
you will need to enter credentials
'admin' & 'password'

  if (!ethernetServer.authenticate("admin", "password"))
    return ethernetServer.requestAuthentication();

Click 'choose file' and find the compiled binary in the sketch folder,
Then click on 'update'
The update should start and you will be notified after 30 seconds when the page automatically refreshes

s += "<META http-equiv='refresh' content='30;URL=/'>Update Success ! Rebooting...\n";

30 seconds is quite long, i don't know how long the process actually takes, but you could experiment with shorter time.

Now if you navigate to the ethernet IP, you should see

Hello from ESP32 Ethernet!, The upload worked !!

to confirm that the newer version is loaded.