

I forgot default. I never selected it and it activated on its own.


I forgot default. I never selected it and it activated on its own.


I just found out about this on mobile firefox must be quite new too. That default opt in is really disgusting.



I really dislike that. But I understand the reaction to the failure of the usb org. Usb C cables must be labelled on the cable (repeating) with exactly what they support in standard terms.
Maybe another job for the EU.
I would argue that even then it’s not great - at least for homelabs.
Raid controlller died? Now you have to get the same one again to get your raid up again. This would be a good moment to upgrade to something more modern usually.


Those damn pre-release notifications though!!! (Githubs fault for not implementing filtering)


We will not vote because it would go against the proposal.
Sounds like a way to avoid setting a precedent or a historic record to me.
In linux user and group names don’t matter. Only the gid and uid matter. Think of user and group names as human names like domains are for IPS.
In docker when you use mounts, all your containers that want to share data must agree on the gid and uids.
In rootless docker and podman things subuids and subgids make it a little more complicated since IDs get mapped between host and container, but its still the IDs that matter.
For what? I use both maybe I should hook them up too. :)


On any modern os unused ram is not simply unused. It is used for caching files and other stuff. So more ram can provide significant performance improvements for some taks even if “unused”.


Well I guess my bubble is pretty strong 😅.


Okay celebrating shareholder value I get in an indoctrinated pure* capitalist society.
But praising a monopoly? Wasn’t that one of the main points capitalism should prevent?
The free market brings about competitors when they are needed.
Which does not hold true in reality due to various reasons and dynamics like entry cost…
Edit: These two are related as monopoly -> big shareholder value. Still the free market should prevent monopolies. Sooo Ahhh.


That story is really sad. To me it seems like a failing of the parents/education system to not teach the son who was 17 that selling a kidney is a bad idea.


There is /s but I opted not to use it. Using it makes the sarcasm less “fun”/rewarding for me.
I am quite surprised at the amount of people that think people exist that would praise a monopoly and celebrate shareholder value. Sadly people thinking that means that they have encountered people who hold such beliefs seriously. Which is quite sad.


I thought the second sentence made that clear but apparently not.


How did you get that downvote? Must have been a mistake.


Monopolies are good for the consumer as it makes purchasing decisions easier. Some tech markets such as the GPU one show how well a monopoly can work for shareholders.


I just wish one could donate to firefox development specifically. Then they could rid it of all the advertisement and tracking stuff.
German: Komm wir essen Opa! Komm wir essen, Opa!
English: Come we are eating grandpa. Come we are eating, grandpa.
I don’t think the promise chain is really needed here.
I used this script:
import Axios from 'axios'
import OldFS from 'fs'
import { PromiseChain } from '@feather-ink/ts-utils'
const fs = OldFS.promises
const image = process.argv[2]
const destination = `http://${process.argv[3]}/vfs/ota`
const now = process.argv[4] === 'now'
const once = process.argv[4] === 'once'
async function triggerUpdate(): Promise<void> {
console.log('Uploading new binary')
const file = await fs.readFile(image)
await Axios({
method: 'POST',
url: destination,
headers: {
'Content-Type': 'application/octet-stream',
'Content-Length': file.byteLength
},
data: file
})
console.log('Finished uploading')
}
(async () => {
const updateChain = new PromiseChain()
console.log(`Watching file '${image}' for changes\nWill upload to '${destination}'!`)
if (once) {
await triggerUpdate()
return
}
if (now)
await updateChain.enqueue(triggerUpdate)
OldFS.watch(image, async (eventType) => {
if (eventType !== 'change')
return
let succ = false
do {
try {
console.log('Change detected')
await updateChain.enqueue(triggerUpdate)
succ = true
} catch (e) {
console.error(e)
console.log('Retrying upload')
}
} while (!succ)
console.log('Upload finished')
})
})()
Relevent code on the esp:
You can ignore my cpp stuff and just put this in the handler of the stock webserver.
auto ota = vfs->addHandler(makeDirectory("ota"));
{
ota->addHandler(makeDirect([](auto &con) {
if (con.req->method != HTTP_POST)
return HandlerReturn::UNHANDLED;
// https://github.com/espressif/esp-idf/tree/master/examples/system/ota/native_ota_example/main
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/ota.html
auto updatePartition = esp_ota_get_next_update_partition(nullptr);
if (updatePartition == nullptr)
return sendError(con,500, "No free ota partition found!");
esp_ota_handle_t otaHandle;
auto err = esp_ota_begin(updatePartition, con.req->content_len, &otaHandle);
if (err != ESP_OK)
return sendError(con, 500, std::string{"Can't start ota update: "} + esp_err_to_name(err), true);
int receivedBytes = 0;
do {
auto end = httpd_req_recv(con.req, buf.data(), buf.size());
// ESP_LOGE(TAG, "Received %d", receivedBytes);
// hexDump("RECV:", buf.data(), end);
if (end <= 0) {
esp_ota_abort(otaHandle);
return sendError(con, 500, "Error receiving", true);
}
err = esp_ota_write(otaHandle, buf.data(), end);
if (err != ESP_OK) {
esp_ota_abort(otaHandle);
return sendError(con, 500, std::string{"Error writing: "} + esp_err_to_name(err), true);
}
receivedBytes += end;
} while (receivedBytes < con.req->content_len);
err = esp_ota_end(otaHandle);
if (err != ESP_OK)
return sendError(con, 500, std::string{"Failed to end: "} + esp_err_to_name(err), true);
err = esp_ota_set_boot_partition(updatePartition);
if (err != ESP_OK)
return sendError(con, 500, std::string{"esp_ota_set_boot_partition failed: "} + esp_err_to_name(err), true);
auto ret = sendOK(con);
FactoryResetServiceCon().reboot(1000 / portTICK_PERIOD_MS);
return ret;
}));
}
I also used a custom partition table for 2 partitions so that when my program crashes it can just go back to boot the previous version.
Here it is for reference:
partitions.csv
# Name, Type, SubType, Offset, Size, Flags
# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
nvs, data, nvs, 0x011000, 0x006000,
otadata, data, ota, 0x017000, 0x002000,
phy_init, data, phy, 0x019000, 0x001000,
ota_0, app, ota_0, 0x020000, 0x1F0000,
ota_1, app, ota_1, 0x210000, 0x1F0000,
Note: This partition table is for a special model of the ESP32 though.
Also another disclaimer: This code does not represent my current coding abilities and may be outdated - it worked well though.
What are you doing for health data and stats?