Canonical Voices

Dustin Kirkland



Yesterday, I delivered a talk to a lively audience at ContainerWorld in Santa Clara, California.

If I measured "the most interesting slides" by counting "the number of people who took a picture of the slide", then by far "the most interesting slides" are slides 8-11, which pose an answer the question:
"Should I run my PaaS on top of my IaaS, or my IaaS on top of my PaaS"?
In the Ubuntu world, that answer is super easy -- however you like!  At Canonical, we're happy to support:
  1. Kubernetes running on top of Ubuntu OpenStack
  2. OpenStack running on top of Canonical Kubernetes
  3. Kubernetes running along side OpenStack
In all cases, the underlying substrate is perfectly consistent:
  • you've got 1 to N physical or virtual machines
  • which are dynamically provisioned by MAAS or your cloud provider
  • running stable, minimal, secure Ubuntu server image
  • carved up into fast, efficient, independently addressable LXD machine containers
With that as your base, we'll easily to conjure-up a Kubernetes, an OpenStack, or both.  And once you have a Kubernetes or OpenStack, we'll gladly conjure-up one inside the other.


As always, I'm happy to share my slides with you here.  You're welcome to download the PDF, or flip through the embedded slides below.



Cheers,
Dustin

Read more
Dustin Kirkland

Introducting the Canonical Livepatch Service
Howdy!

Ubuntu 16.04 LTS’s 4.4 Linux kernel includes an important new security capability in Ubuntu -- the ability to modify the running Linux kernel code, without rebooting, through a mechanism called kernel livepatch.

Today, Canonical has publicly launched the Canonical Livepatch Service -- an authenticated, encrypted, signed stream of Linux livepatches that apply to the 64-bit Intel/AMD architecture of the Ubuntu 16.04 LTS (Xenial) Linux 4.4 kernel, addressing the highest and most critical security vulnerabilities, without requiring a reboot in order to take effect.  This is particularly amazing for Container hosts -- Docker, LXD, etc. -- as all of the containers share the same kernel, and thus all instances benefit.



I’ve tried to answer below some questions that you might have. As you have others, you’re welcome
to add them to the comments below or on Twitter with hastag #Livepatch.

Retrieve your token from ubuntu.com/livepatch

Q: How do I enable the Canonical Livepatch Service?

A: Three easy steps, on a fully up-to-date 64-bit Ubuntu 16.04 LTS system.
  1. Go to https://ubuntu.com/livepatch and retrieve your livepatch token
    1. Install the canonical-livepatch snap
      $ sudo snap install canonical-livepatch 
    2. Enable the service with your token
      $ sudo canonical-livepatch enable [TOKEN] 
    And you’re done! You can check the status at any time using:

    $ canonical-livepatch status --verbose

      Q: What are the system requirements?

      A: The Canonical Livepatch Service is available for the generic and low latency flavors of the 64-bit Intel/AMD (aka, x86_64, amd64) builds of the Ubuntu 16.04 LTS (Xenial) kernel, which is a Linux 4.4 kernel. Canonical livepatches work on Ubuntu 16.04 LTS Servers and Desktops, on physical machines, virtual machines, and in the cloud. The safety, security, and stability firmly depends on unmodified Ubuntu kernels and network access to the Canonical Livepatch Service (https://livepatch.canonical.com:443).  You also will need to apt update/upgrade to the latest version of snapd (at least 2.15).

      Q: What about other architectures?

      A: The upstream Linux livepatch functionality is currently limited to the 64-bit x86 architecture, at this time. IBM is working on support for POWER8 and s390x (LinuxOne mainframe), and there’s also active upstream development on ARM64, so we do plan to support these eventually. The livepatch plumbing for 32-bit ARM and 32-bit x86 are not under upstream development at this time.

      Q: What about other flavors?

      A: We are providing the Canonical Livepatch Service for the generic and low latency (telco) flavors of the the Linux kernel at this time.

      Q: What about other releases of Ubuntu?

      A: The Canonical Livepatch Service is provided for Ubuntu 16.04 LTS’s Linux 4.4 kernel. Older releases of Ubuntu will not work, because they’re missing the Linux kernel support. Interim releases of Ubuntu (e.g. Ubuntu 16.10) are targeted at developers and early adopters, rather than Long Term Support users or systems that require maximum uptime.  We will consider providing livepatches for the HWE kernels in 2017.

      Q: What about derivatives of Ubuntu?

      A: Canonical livepatches are fully supported on the 64-bit Ubuntu 16.04 LTS Desktop, Cloud, and Server operating systems. On other Ubuntu derivatives, your mileage may vary! These are not part of our automated continuous integration quality assurance testing framework for Canonical Livepatches. Canonical Livepatch safety, security, and stability will firmly depend on unmodified Ubuntu generic kernels and network access to the Canonical Livepatch Service.

      Q: How does Canonical test livepatches?

      A: Every livepatch is rigorously tested in Canonical's in-house CI/CD (Continuous Integration / Continuous Delivery) quality assurance system, which tests hundreds of combinations of livepatches, kernels, hardware, physical machines, and virtual machines.  Once a livepatch passes CI/CD and regression tests, it's rolled out on a canary testing basis, first to a tiny percentage of the Ubuntu Community users of the Canonical Livepatch Service. Based on the success of that microscopic rollout, a moderate rollout follows.  And assuming those also succeed, the livepatch is delivered to all free Ubuntu Community and paid Ubuntu Advantage users of the service.  Systemic failures are automatically detected and raised for inspection by Canonical engineers.  Ubuntu Community users of the Canonical Livepatch Service who want to eliminate the small chance of being randomly chosen as a canary should enroll in the Ubuntu Advantage program (starting at $12/month).

      Q: What kinds of updates will be provided by the Canonical Livepatch Service?

      A: The Canonical Livepatch Service is intended to address high and critical severity Linux kernel security vulnerabilities, as identified by Ubuntu Security Notices and the CVE database. Note that there are some limitations to the kernel livepatch technology -- some Linux kernel code paths cannot be safely patched while running. We will do our best to supply Canonical Livepatches for high and critical vulnerabilities in a timely fashion whenever possible. There may be occasions when the traditional kernel upgrade and reboot might still be necessary. We’ll communicate that clearly through the usual mechanisms -- USNs, Landscape, Desktop Notifications, Byobu, /etc/motd, etc.

      Q: What about non-security bug fixes, stability, performance, or hardware enablement updates?

      A: Canonical will continue to provide Linux kernel updates addressing bugs, stability issues, performance problems, and hardware compatibility on our usual cadence -- about every 3 weeks. These updates can be easily applied using ‘sudo apt update; sudo apt upgrade -y’, using the Desktop “Software Updates” application, or Landscape systems management. These standard (non-security) updates will still require a reboot, as they always have.

      Q: Can I rollback a Canonical Livepatch?

      A: Currently rolling-back/removing an already inserted livepatch module is disabled in Linux 4.4. This is because we need a way to determine if we are currently executing inside a patched function before safely removing it. We can, however, safely apply new livepatches on top of each other and even repatch functions over and over.

      Q: What about low and medium severity CVEs?

      A: We’re currently focusing our Canonical Livepatch development and testing resources on high and critical security vulnerabilities, as determined by the Ubuntu Security Team.  We'll livepatch other CVEs opportunistically.

      Q: Why are Canonical Livepatches provided as a subscription service?

      A: The Canonical Livepatch Service provides a secure, encrypted, authenticated connection, to ensure that only properly signed livepatch kernel modules -- and most importantly, the right modules -- are delivered directly to your system, with extremely high quality testing wrapped around it.

      Q: But I don’t want to buy UA support!

      A: You don’t have to! Canonical is providing the Canonical Livepatch Service to community users of Ubuntu, at no charge for up to 3 machines (desktop, server, virtual machines, or cloud instances). A randomly chosen subset of the free users of Canonical Livepatches will receive their Canonical Livepatches slightly earlier than the rest of the free users or UA users, as a lightweight canary testing mechanism, benefiting all Canonical Livepatch users (free and UA). Once those canary livepatches apply safely, all Canonical Livepatch users will receive their live updates.

      Q: But I don’t have an Ubuntu SSO account!

      A: An Ubuntu SSO account is free, and provides services similar to Google, Microsoft, and Apple for Android/Windows/Mac devices, respectively. You can create your Ubuntu SSO account here.

      Q: But I don’t want login to ubuntu.com!

      A: You don’t have to! Canonical Livepatch is absolutely not required maintain the security of any Ubuntu desktop or server! You may continue to freely and anonymously ‘sudo apt update; sudo apt upgrade; sudo reboot’ as often as you like, and receive all of the same updates, and simply reboot after kernel updates, as you always have with Ubuntu.

      Q: But I don't have Internet access to livepatch.canonical.com:443!

      A: You should think of the Canonical Livepatch Service much like you think of Netflix, Pandora, or Dropbox.  It's an Internet streaming service for security hotfixes for your kernel.  You have access to the stream of bits when you can connect to the service over the Internet.  On the flip side, your machines are already thoroughly secured, since they're so heavily firewalled off from the rest of the world!

      Q: Where’s the source code?

      A: The source code of livepatch modules can be found here.  The source code of the canonical-livepatch client is part of Canonical's Landscape system management product and is commercial software.

      Q: What about Ubuntu Core?

      A: Canonical Livepatches for Ubuntu Core are on the roadmap, and may be available in late 2016, for 64-bit Intel/AMD architectures. Canonical Livepatches for ARM-based IoT devices depend on upstream support for livepatches.

      Q: How does this compare to Oracle Ksplice, RHEL Live Patching and SUSE Live Patching?

      A: While the concepts are largely the same, the technical implementations and the commercial terms are very different:

      • Oracle Ksplice uses it’s own technology which is not in upstream Linux.
      • RHEL and SUSE currently use their own homegrown kpatch/kgraft implementations, respectively.
      • Canonical Livepatching uses the upstream Linux Kernel Live Patching technology.
      • Ksplice is free, but unsupported, for Ubuntu Desktops, and only available for Oracle Linux and RHEL servers with an Oracle Linux Premier Support license ($2299/node/year).
      • It’s a little unclear how to subscribe to RHEL Kernel Live Patching, but it appears that you need to first be a RHEL customer, and then enroll in the SIG (Special Interests Group) through your TAM (Technical Account Manager), which requires Red Hat Enterprise Linux Server Premium Subscription at $1299/node/year.  (I'm happy to be corrected and update this post)
      • SUSE Live Patching is available as an add-on to SUSE Linux Enterprise Server 12 Priority Support subscription at $1,499/node/year, but does come with a free music video.
      • Canonical Livepatching is available for every Ubuntu Advantage customer, starting at our entry level UA Essential for $150/node/year, and available for free to community users of Ubuntu.

      Q: What happens if I run into problems/bugs with Canonical Livepatches?

      A: Ubuntu Advantage customers will file a support request at support.canonical.com where it will be serviced according to their UA service level agreement (Essential, Standard, or Advanced). Ubuntu community users will file a bug report on Launchpad and we'll service it on a best effort basis.

      Q: Why does canonical-livepatch client/server have a proprietary license?

      A: The canonical-livepatch client is part of the Landscape family of tools available to Canonical support customers. We are enabling free access to the Canonical Livepatch Service for Ubuntu community users as a mark of our appreciation for the broader Ubuntu community, and in exchange for occasional, automatic canary testing.

      Q: How do I build my own livepatches?

      A: It’s certainly possible for you to build your own Linux kernel live patches, but it requires considerable skill, time, computing power to produce, and even more effort to comprehensively test. Rest assured that this is the real value of using the Canonical Livepatch Service! That said, Chris Arges has blogged a howto for the curious a while back:

      http://chrisarges.net/2015/09/21/livepatch-on-ubuntu.html

      Q: How do I get notifications of which CVEs are livepatched and which are not?

      A: You can, at any time, query the status of the canonical-livepatch daemon using: ‘canonical-livepatch status --verbose’. This command will show any livepatches successfully applied, any outstanding/unapplied livepatches, and any error conditions. Moreover, you can monitor the Ubuntu Security Notices RSS feed and the ubuntu-security-announce mailing list.

      Q: Isn't livepatching just a big ole rootkit?

      A: Canonical Livepatches inject kernel modules to replace sections of binary code in the running kernel. This requires the CAP_SYS_MODULE capability. This is required to modprobe any module into the Linux kernel. If you already have that capability (root does, by default, on Ubuntu), then you already have the ability to arbitrarily modify the kernel, with or without Canonical Livepatches. If you’re an Ubuntu sysadmin and you want to disable module loading (and thereby also disable Canonical Livepatches), simply ‘echo 1 | sudo tee /proc/sys/kernel/modules_disabled’.

      Keep the uptime!
      :-Dustin

      Read more
      Alan Griffiths

      miral-workspaces

      “Workspaces” have arrived on MirAL trunk (lp:miral).

      We won’t be releasing 1.3 with this feature just yet (as we want some experience with this internally first). But if you build from source there’s an example to play with (bin/miral-app).

      As always, bug reports and other suggestions are welcome.

      Note that the miral-shell doesn’t have transitions and other effects like fully featured desktop environments.

      Read more
      facundo

      Resumen veraniego de películas


      Muchas, muchas películas vistas. Igual no entro en ritmo en ver más; estoy complicado en encontrar ese par de horas en que los niños están tranquilos y yo no estoy muy cansado :p

      • Alice Through the Looking Glass: +0. Divertida, un flash, pero tampoco mucho más que una colección de momentos interesantes.
      • All Is Lost: -0. La supervivencia de alguien con una seguidilla de malas suertes; mirala sólo si te interesa esto de "estar solo y sobrevivir como se pueda".
      • Captain America: Civil War: +0. La típica pelea entre superheroes, pero no se me hizo pesada; de bonus tiene una temática interesante de pensar, sobre el control de gobiernos sobre las armas.
      • Clouds of Sils Maria: -0. Aunque tiene muchas charlas interesantes, la historia en sí no tiene ritmo, y no va a ningún lado.
      • Danny Collins: +0. Linda historia, no del todo esperado lo que sucede, emotiva, bien armada.
      • El Ardor: +0. Buena la historia, buena la ambientación, y creo que muestra bien una realidad que conocemos muy poco.
      • Ex Machina: -0. No me gustó, pero no sé bien por qué. ¿Le faltó suspenso? ¿Muy plana? Lo que plantean a nivel inteligencia artificial está bien, sin embargo (me hubiese gustado más profundidad, pero bueno, es una película para las masas, no un documental).
      • Fantastic Four: -0. Un punto de vista diferente del clásico, pero bleh.
      • Home Sweet Hell: -0. Con sus partes muy graciosas, pero la historia no llega a ser.
      • La Vénus à la fourrure: +1. La dinámica entre dos personas, la linea entre la realidad y la ficción. Me encantó.
      • Laggies: +0. Apenas lenta, pero buena historia, buen desarrollo, me gustó como muestra la evolución de la decisión del personaje principal.
      • Match: +0. Linda historia, buenas actuaciones. Potente.
      • Nina: +1. Mis más grandes respetos para Zoe Saldaña. Maravillosa. Deslumbrante. Me gustaría saber qué piensa una o un fan de Nina Simone sobre esta película.
      • Pan: -0. Una versión distinta del clásico, bastante renovada, no me llegó a atrapar.
      • Pixels: +0. Divertida y pasatista, me gustó estando Adam Sandler y todo. Tampoco es la gran cosa, eh, pero es más que nada piola en función de los videojuegos viejos...
      • Predestination: +1. Muy buena historia, no vas entendiendo de qué va hasta que te enroscó y después ya caiste en la (buena) trampa.
      • Stealing Beauty: -0. Una linda historia, una maravillosa fotografía, pero le falta "consistencia", es muy etérea, no sé. Y lenta.
      • The November Man: -0. Una de acción y espías wannabe, no mucho.
      • The Right Kind of Wrong: +0. Sólo una comedia romántica, pasatista, pero divertida.
      • Time Lapse: +1. LA historia no es muy profunda, pero maneja muy bien la temporalidad (o los saltos en la misma...).
      • Under the Skin: -1. Hay una historia, ahí, pero la película es EXTREMADAMENTE lenta :(.
      • VANish: -0. Bruta, violenta, y cruda. Pero nada más.
      • Vice: -0. Con algunos dejos de temática interesante, en la que podrían haber incursionado sobre la parte conceptual de los robots, pero la película va por otro lado.


      Un montonazo para ver! Y eso que no estoy encontrando un buen lugar para enterarme de los trailers que van saliendo. Por ahora estoy usando este canal de YouTube, pero no tiene todo. Me sugirieron IMDb, también, pero aunque tiene algunas cosas que el otro no, tiene muy poco y no parece estar del todo bien ordenado.

      • Amateur (2016; Thriller) Martin (Esteban Lamothe) is a lonely television director, who becomes obsessed with his neighbor, Isabel (Jazmin Stuart), when he finds an amateur porn video in which she participates. But Isabel is the wife of Battaglia (Alejandro Awada), the owner of the television station where Martin works. As a strange love encounter takes place between Martin and Isabel, he discovers a secret that puts them both in danger. [D: Sebastian Perillo; A: Alejandro Awada, Esteban Lamothe, Jazmín Stuart]
      • Blade Runner 2049 (2017; Sci-Fi) Thirty years after the events of the first film, a new blade runner, LAPD Officer K (Ryan Gosling), unearths a long-buried secret that has the potential to plunge what's left of society into chaos. K's discovery leads him on a quest to find Rick Deckard (Harrison Ford), a former LAPD blade runner who has been missing for 30 years. [D: Denis Villeneuve; A: Ryan Gosling, Ana de Armas, Jared Leto]
      • Colossal (2016; Action, Sci-Fi, Thriller) A woman discovers that severe catastrophic events are somehow connected to the mental breakdown from which she's suffering. [D: Nacho Vigalondo; A: Dan Stevens, Anne Hathaway, Jason Sudeikis]
      • DxM (2015; Action, Sci-Fi, Thriller) A group of brilliant young students discover the greatest scientific breakthrough of all time: a wireless neural network, connected via a quantum computer, capable of linking the minds of each and every one of us. They realise that quantum theory can be used to transfer motor-skills from one brain to another, a first shareware for human motor-skills. They freely spread this technology, believing it to be a first step towards a new equality and intellectual freedom. But they soon discover that they themselves are part of a much greater and more sinister experiment as dark forces emerge that threaten to subvert this technology into a means of mass-control. MindGamers takes the mind-bender thriller to the next level with an immersive narrative and breath-taking action. [D: Andrew Goth; A: Dominique Tipper, Sam Neill, Tom Payne]
      • Elle (2016; Comedy, Drama, Thriller) Michèle seems indestructible. Head of a successful video game company, she brings the same ruthless attitude to her love life as to business. Being attacked in her home by an unknown assailant changes Michèle's life forever. When she resolutely tracks the man down, they are both drawn into a curious and thrilling game-a game that may, at any moment, spiral out of control. [D: Paul Verhoeven; A: Isabelle Huppert, Laurent Lafitte, Anne Consigny]
      • Frank & Lola (2016; Crime, Drama, Mystery, Romance, Thriller) A psychosexual noir love story, set in Las Vegas and Paris, about love, obsession, sex, betrayal, revenge and, ultimately, the search for redemption. [D: Matthew Ross; A: Imogen Poots, Michael Shannon, Michael Nyqvist]
      • Ghost in the Shell (2017; Action, Drama, Sci-Fi, Thriller) Based on the internationally acclaimed sci-fi manga series, "Ghost in the Shell" follows the Major, a special ops, one-of-a-kind human cyborg hybrid, who leads the elite task force Section 9. Devoted to stopping the most dangerous criminals and extremists, Section 9 is faced with an enemy whose singular goal is to wipe out Hanka Robotic's advancements in cyber technology. [D: Rupert Sanders; A: Scarlett Johansson, Michael Pitt, Michael Wincott]
      • Guardians of the Galaxy Vol. 2 (2017; Action, Sci-Fi) Set to the backdrop of 'Awesome Mixtape #2,' Marvel's Guardians of the Galaxy Vol. 2 continues the team's adventures as they traverse the outer reaches of the cosmos. The Guardians must fight to keep their newfound family together as they unravel the mysteries of Peter Quill's true parentage. Old foes become new allies and fan-favorite characters from the classic comics will come to our heroes' aid as the Marvel cinematic universe continues to expand. [D: James Gunn; A: Chris Sullivan, Pom Klementieff, Chris Pratt]
      • Kiki, el amor se hace (2016; Comedy) Through five stories, the movie addresses sex and love: Paco and Ana are a marriage looking for reactivate the passion of their sexual relations, long time unsatisfied; Jose Luis tries to recover the affections of his wife Paloma, sit down on a wheelchair after an accident which has limited her mobility; Mª Candelaria and Antonio are a marriage trying by all way to be parents, but she has the trouble that no get an orgasm when make love with him; Álex try to satisfy Natalia's fantasies, while she starts to doubt if he finally will ask her in marriage; and finally, Sandra is a single woman in a permanent searching for a man to fall in love. All them love, fear, live and explore their diverse sexual paraphilias and the different sides of sexuality, trying to find the road to happiness. [D: Paco León; A: Natalia de Molina, Álex García, Jacobo Sánchez]
      • Life (2017; Horror, Sci-Fi, Thriller) Six astronauts aboard the space station study a sample collected from Mars that could provide evidence for extraterrestrial life on the Red Planet. The crew determines that the sample contains a large, single-celled organism - the first example of life beyond Earth. But..things aren't always what they seem. As the crew begins to conduct research, and their methods end up having unintended consequences, the life form proves more intelligent than anyone ever expected. [D: Daniel Espinosa; A: Rebecca Ferguson, Jake Gyllenhaal, Ryan Reynolds]
      • Little Murder (2011; Crime, Drama, Thriller) In post-Katrina New Orleans, a disgraced detective encounters the ghost of a murdered woman who wants to help him identify her killer. [D: Predrag Antonijevic; A: Josh Lucas, Terrence Howard, Lake Bell]
      • Logan (2017; Action, Drama, Sci-Fi) In the near future, a weary Logan cares for an ailing Professor X in a hide out on the Mexican border. But Logan's attempts to hide from the world and his legacy are up-ended when a young mutant arrives, being pursued by dark forces. [D: James Mangold; A: Doris Morgado, Hugh Jackman, Dafne Keen]
      • Passengers (2016; Adventure, Drama, Romance, Sci-Fi) The spaceship, Starship Avalon, in its 120-year voyage to a distant colony planet known as the "Homestead Colony" and transporting 5,258 people has a malfunction in one of its sleep chambers. As a result one hibernation pod opens prematurely and the one person that awakes, Jim Preston (Chris Pratt) is stranded on the spaceship, still 90 years from his destination. [D: Morten Tyldum; A: Jennifer Lawrence, Chris Pratt, Michael Sheen]
      • Personal Shopper (2016; Drama, Mystery, Thriller) Revolves around a ghost story that takes place in the fashion underworld of Paris. [D: Olivier Assayas; A: Kristen Stewart, Lars Eidinger, Sigrid Bouaziz]
      • Pirates of the Caribbean: Dead Men Tell No Tales (2017; Action, Adventure, Comedy, Fantasy) Captain Jack Sparrow finds the winds of ill-fortune blowing even more strongly when deadly ghost pirates led by his old nemesis, the terrifying Captain Salazar, escape from the Devil's Triangle, determined to kill every pirate at sea...including him. Captain Jack's only hope of survival lies in seeking out the legendary Trident of Poseidon, a powerful artifact that bestows upon its possessor total control over the seas. [D: Joachim Rønning, Espen Sandberg; A: Kaya Scodelario, Johnny Depp, Javier Bardem]
      • Spider-Man: Homecoming (2017; Action, Adventure, Sci-Fi) A young Peter Parker/Spider-Man, who made his sensational debut in Captain America: Civil War, begins to navigate his newfound identity as the web-slinging superhero in Spider-Man: Homecoming. Thrilled by his experience with the Avengers, Peter returns home, where he lives with his Aunt May, under the watchful eye of his new mentor Tony Stark, Peter tries to fall back into his normal daily routine - distracted by thoughts of proving himself to be more than just your freindly neighborhood Spider-Man - but when the Vulture emerges as a new villain, everything that Peter holds most important will be threatened. [D: Jon Watts; A: Robert Downey Jr., Tom Holland, Angourie Rice]
      • T2 Trainspotting (2017; Comedy, Drama) First there was an opportunity......then there was a betrayal. Twenty years have gone by. Much has changed but just as much remains the same. Mark Renton (Ewan McGregor) returns to the only place he can ever call home. They are waiting for him: Spud (Ewen Bremner), Sick Boy (Jonny Lee Miller), and Begbie (Robert Carlyle). Other old friends are waiting too: sorrow, loss, joy, vengeance, hatred, friendship, love, longing, fear, regret, diamorphine, self-destruction and mortal danger, they are all lined up to welcome him, ready to join the dance. [D: Danny Boyle; A: Ewan McGregor, Logan Gillies, Ben Skelton]
      • The Discovery (2017; Romance, Sci-Fi) Writer-director Charlie McDowell returns to Sundance this year with a thriller about a scientist (played by Robert Redford) who uncovers scientific proof that there is indeed an afterlife. His son is portrayed by Jason Segel, who's not too sure about his father's "discovery", and Rooney Mara plays a mystery woman who has her own reasons for wanting to find out more about the afterlife. [D: Charlie McDowell; A: Rooney Mara, Riley Keough, Robert Redford]
      • The Whole Truth (2016; Drama, Thriller) Defense attorney Richard Ramsay takes on a personal case when he swears to his widowed friend, Loretta Lassiter, that he will keep her son Mike out of prison. Charged with murdering his father, Mike initially confesses to the crime. But as the trial proceeds, chilling evidence about the kind of man that Boone Lassiter really was comes to light. While Ramsay uses the evidence to get his client acquitted, his new colleague Janelle tries to dig deeper - and begins to realize that the whole truth is something she alone can uncover. [D: Courtney Hunt; A: Keanu Reeves, Renée Zellweger, Gugu Mbatha-Raw]
      • The Comedian (2016; Comedy) A look at the life of an aging insult comic named Jack Burke. [D: Taylor Hackford; A: Robert De Niro, Leslie Mann, Harvey Keitel]
      • The Mummy (2017; Action, Adventure, Fantasy, Horror) Though safely entombed in a crypt deep beneath the unforgiving desert, an ancient princess whose destiny was unjustly taken from her is awakened in our current day, bringing with her malevolence grown over millennia, and terrors that defy human comprehension. [D: Alex Kurtzman; A: Tom Cruise, Sofia Boutella, Russell Crowe]
      • Valerian and the City of a Thousand Planets (2017; Action, Adventure, Sci-Fi) Rooted in the classic graphic novel series, Valerian and Laureline- visionary writer/director Luc Besson advances this iconic source material into a contemporary, unique and epic science fiction saga. Valerian (Dane DeHaan) and Laureline (Cara Delevingne) are special operatives for the government of the human territories charged with maintaining order throughout the universe. Valerian has more in mind than a professional relationship with his partner- blatantly chasing after her with propositions of romance. But his extensive history with women, and her traditional values, drive Laureline to continuously rebuff him. Under directive from their Commander (Clive Owen), Valerian and Laureline embark on a mission to the breathtaking intergalactic city of Alpha, an ever-expanding metropolis comprised of thousands of different species from all four corners of the universe. Alpha's seventeen million inhabitants have converged over time- uniting their talents, technology and resources for the betterment of all. Unfortunately, not everyone on Alpha shares in these same objectives; in fact, unseen forces are at work, placing our race in great danger. [D: Luc Besson; A: Dane DeHaan, Cara Delevingne, Ethan Hawke]
      • Vampyres (2015; Horror) Faithful to the sexy, twisted 1974 cult classic by Joseph Larraz, Vampyres is an English-language remake pulsating with raw eroticism, wicked sado-masochism and bloody, creative gore. Victor Matellano (Wax (2014, Zarpazos! A Journey through Spanish Horror, 2013) directs this tale set in a stately English manor inhabited by two older female vampires and with their only cohabitant being a man imprisoned in the basement. Their lives and lifestyle are upended when a trio of campers come upon their lair and seek to uncover their dark secrets, a decision that has sexual and blood-curdling consequences. [D: Víctor Matellano; A: Marta Flich, Almudena León, Alina Nastase]
      • Zero Days (2016; Documentary) Documentary detailing claims of American/Israeli jointly developed malware Stuxnet being deployed not only to destroy Iranian enrichment centrifuges but also threaten attacks against Iranian civilian infrastructure. Adresses obvious potential blowback of this possibly being deployed against the US by Iran in retaliation. [D: Alex Gibney; A: David Sanger, Emad Kiyaei, Eric Chien]
      • Collateral Beauty (2016; Drama, Romance) When a successful New York advertising executive suffers a great tragedy, he retreats from life. While his concerned friends try desperately to reconnect with him, he seeks answers from the universe by writing letters to Love, Time and Death. But it's not until his notes bring unexpected personal responses that he begins to understand how these constants interlock in a life fully lived, and how even the deepest loss can reveal moments of meaning and beauty [D: David Frankel; A: Will Smith, Edward Norton, Kate Winslet]
      • Passage to Mars (2016; Documentary, Adventure) The journals of a true NASA Arctic expedition unveils the adventure of a six-man crew's aboard an experimental vehicle designed to prepare the first human exploration of Mars. A voyage of fears and survival, hopes and dreams, through the beauties and the deadly dangers of two worlds: the High Arctic and Mars, a planet that might hide the secret of our origins. [D: Jean-Christophe Jeauffre; A: Zachary Quinto, Charlotte Rampling, Pascal Lee]


      Finalmente, el conteo de pendientes por fecha:

      (Abr-2011)    4
      (Ago-2011)   11   4
      (Ene-2012)   17  11   3
      (Jul-2012)   15  14  11
      (Nov-2012)   11  11  11   6
      (Feb-2013)   15  14  14   8   2
      (Jun-2013)   16  15  15  15  11   2
      (Sep-2013)   18  18  18  17  16   8
      (Dic-2013)   14  14  12  12  12  12   4
      (Abr-2014)        9   9   8   8   8   3
      (Jul-2014)           10  10  10  10  10   5   1
      (Nov-2014)               24  22  22  22  22   7
      (Feb-2015)                   13  13  13  13  10
      (Jun-2015)                       16  16  15  13  11
      (Dic-2015)                           21  19  19  18
      (May-2016)                               26  25  23
      (Sep-2016)                                   19  19
      (Feb-2017)                                       26
      Total:      121 110 103 100  94  91  89 100  94  97

      Read more
      Alan Griffiths

      MirAL 1.2

      There’s a new MirAL release (1.2.0) available in ‘Zesty Zapus’ (Ubuntu 17.04) and the so-called “stable phone overlay” ppa for ‘Xenial Xerus’ (Ubuntu 16.04LTS). MirAL is a project aimed at simplifying the development of Mir servers and particularly providing a stable ABI and sensible default behaviors.

      Unsurprisingly, given the project’s original goal, the ABI is unchanged.

      Since my last update the integration of libmiral into QtMir has progressed and libmiral has been used in the latest updates to Unity8.

      The changes in 1.2.0 fall are:

      A new libmirclientcpp-dev package

      This is a “C++ wrapper for libmirclient” and has been split
      from libmiral-dev.

      Currently it comprises RAII wrappers for some Mir client library types: MirConnection, MirWindowSpec, MirWindow and MirWindowId. In addition, the WindowSpec wrapper provides named constructors and function chaining to enable code like the following:

      auto const window = mir::client::WindowSpec::
          for_normal_window(connection, 50, 50, mir_pixel_format_argb_8888)
          .set_buffer_usage(mir_buffer_usage_software)
          .set_name(a_window.c_str())
          .create_window();
      

      Refresh the “Building and Using MirAL” doc

      This has been rewritten (and renamed) to reflect the presence of MirAL in the Ubuntu archives and make installation (rather than “build it yourself”) the default approach.

      Bug fixes

      • [libmiral] Chrome-less shell hint does not work any more (LP: #1658117)
      • “$ miral-app -kiosk” fails with “Unknown command line options:
        –desktop_file_hint=miral-shell.desktop” (LP: #1660933)
      • [libmiral] Fix focus and movement rules for Input Method and Satellite
        windows. (LP: #1660691)
      • [libmirclientcpp-dev] WindowSpec::set_state() wrapper for mir_window_spec_set_state()
        (LP: #1661256)

      Read more

      Snappy Libertine

      Libertine is software suite for runnin X11 apps in non-X11 environments and installing deb-based applications on a system without dpkg. Snappy is a package management system to confine applications from one another. Wouldn’t it be cool to run libertine as a snap?

      Yes. Yes it would.

      snapd

      The first thing to install is snapd itself. You can find installation instructions for many Linux distros at snapcraft.io, but here’s the simple command if you’re on a debian-based operating system:

      1
      
      $ sudo apt install snapd
      

      Ubuntu users may be surprised to find that snapd is already installed on their systems. snapd is the daemon for handling all things snappy: installing, removing, handling interface connections, etc.

      lxd

      We use lxd as our container backend for libertine in the snap. lxd is essentially a layer on top of lxc to give a better user experience. Fortunately for us, lxd has a snap all ready to go. Unfortunately, the snap version of lxd is incompatible with the deb-based version, so you’ll need to completely remove that before continuing. Skip this step if you never installed lxd:

      1
      2
      3
      4
      
      $ sudo apt remove --purge lxd lxd-client
      $ sudo zpool destroy lxd                 # if you use zfs
      $ sudo ip link set lxdbr0 down           # take down the bridge (lxdbr0 is the default)
      $ sudo brctl delbr lxdbr0                # delete the bridge
      

      For installing, in-depth instructions can be found in this blog post by one of the lxd devs. In short, we’re going to create a new group called lxd, add ourselves to it, and then add our own user ID and group ID to map to root within the container.

      1
      2
      3
      4
      5
      6
      
      $ sudo groupadd --system lxd                      # Create the group on your system
      $ sudo usermod -G lxd -a $USER                    # Add the current user
      $ newgrp lxd                                      # update current session with new group
      $ echo root:`id --user ${USER}`:1 >> /etc/subuid  # Setup subuid to map correctly
      $ echo root:`id --group ${USER}`:1 >> /etc/subgid # Setup subgid to map correctly
      $ sudo snap install lxd                           # actually install the snap!
      

      We also need to initialize lxd manually. For me, the defaults all work great. The important pieces here are setting up a new network bridge and a new filestore for lxd to use. You can optionally use zfs if you have it installed (zfsutils-linux should do it on Ubuntu). Generally, I just hit “return” as fast as the questions show up and everything turns out alright. If anything goes wrong, you may need to manually delete zpools, network bridges, or reinstall the lxd snap. No warranties here.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      
      $ sudo lxd init
      Do you want to configure a new storage pool (yes/no) [default=yes]?
      Name of the new storage pool [default=default]:
      Name of the storage backend to use (dir or zfs) [default=zfs]:
      Create a new ZFS pool (yes/no) [default=yes]?
      Would you like to use an existing block device (yes/no) [default=no]?
      Would you like LXD to be available over the network (yes/no) [default=no]?
      Would you like stale cached images to be updated automatically (yes/no) [default=yes]?
      Would you like to create a new network bridge (yes/no) [default=yes]?
      What should the new bridge be called [default=lxdbr0]?
      What IPv4 address should be used (CIDR subnet notation, “auto” or “none”) [default=auto]?
      

      You should now be able to run lxd.lxc list without errors. It may warn you about running lxd init, but don’t worry about that if your initialization succeeded.

      libertine

      Now we’re onto the easy part. libertine is only available from edge channels in the app store, but we’re fairly close to having a version that we could push into more stable channels. For the latest and greatest libertine:

      1
      2
      
      $ sudo snap install --edge libertine
      $ sudo snap connect libertine:libertined-client libertine:libertined
      

      If we want libertine to work fully, we need to jump through a couple of hoops. For starters, dbus-activation is not fully functional at this time for snaps. Lucky for us, we can fake this by either running the d-bus service manually (/snap/bin/libertined), or by adding this file to /usr/share/dbus-1/services/com.canonical.libertine.Service.service

      /usr/share/dbus-1/services/com.canonical.libertine.Service.service
      1
      2
      3
      
      [D-BUS Service]
      Name=com.canonical.libertine.Service
      Exec=/snap/bin/libertine.libertined --cache-output
      

      Personally, I always create the file, which will allow libertined to start automatically on the session bus whenever a user calls it. Hopefully d-bus activation will be fixed sooner rather than later, but this works fine for now.

      Another issue is that existing deb-based libertine binaries may conflict with the snap binaries. We can fix this by adjusting PATH in our .bashrc file:

      $HOME/.bashrc
      1
      2
      
      # ...
      export PATH=/snap/bin:$PATH
      

      This will give higher priority to snap binaries (which should be the default, IMO). One more thing to fix before running full-force is to add an environment variable to /etc/environment such that the correct libertine binary is picked up in Unity 8:

      /etc/environment
      1
      2
      
      # ...
      UBUNTU_APP_LAUNCH_LIBERTINE_LAUNCH=/snap/bin/libertine-launch
      

      OK! Now we’re finally ready to start creating containers and installing packages:

      1
      2
      3
      4
      
      $ libertine-container-manager create -i my-container
      # ... (this could take a few minutes)
      $ libertine-container-manager install-package -i my-container -p xterm
      # ... (and any other packages you may want)
      

      If you want to launch your apps in Unity 7 (why not?):

      1
      2
      
      $ libertine-launch -i my-container xterm
      # ... (lots of ourput, hopefully an open window!)
      

      When running Unity 8, your apps should show up in the app drawer with all the other applications. This will all depend on libertined running, so make sure that it runs at startup!

      I’ve been making a lot of improvements on the snap lately, especially as the ecosystem continues to mature. One day we plan for a much smoother experience, but this current setup will let us work out some of the kinks and find issues. If you want to switch back the deb-based libertine, you can just install it through apt and remove the change to /etc/environment.

      Read more
      facundo

      Vacaciones en Neuquén


      En enero nos tomamos con la familia un par de semanas y nos fuimos a pasar unas vacaciones en Neuquén. Como siempre, hicimos el viaje en dos días, pero la novedad es que no fuimos solos, ibamos en "caravana de dos autos", nosotros y mi mamá y Diana en el otro.

      El lugar base, como en otras oportunidades, fue la casa que se están armando Diana y Gus en Piedra del Águila. Allí estuvimos varios días, e hicimos de todo.

      Parando a almorzar en la ruta, ¡ni un árbol!

      Obviamente, un punto fuerte fue el comer :p. Es que es un clásico: el horno de barro construido por Di es un golazo. Ahí hicimos un pernil de cerdo con verduras, un costillar de cerdo y bondiola, también con verduras (tirar cuatro o cinco choclos con las chalas adentro y dejarlos una horita lo hacíamos siempre!), pizzas caseras, de todo.

      Para bajar la comida (?) paseamos bastante. Algunas recorridas sólo para descansar, como un paseito pequeño una tarde al perilago (nos metimos al agua, que estaba linda), o un día en la vera del Río Limay, justo abajo del Embalse de Pichí Picún Leufú, donde también almorzamos. La pasaron bien hasta los perros, Mafalda (como pudo, con las piedras, está muy viejita) y Fidel. Nosotros nos divertimos tirando piedras con Gus, Felu y hasta Male! Y obvio: descansamos, dormimos, caminamos por el agua, etc.

      Por otro lado, también hicimos un paseo por los cerros de Piedra del Águila, escalando bastante, paseando por las cimas, esquivando cardos y pinches varios, bajando con mucho cuidado. Male se la re bancó. Felu iba como loco. Estuvo muy bueno, incluso haciendo tanto tantísimo viento en la cima (te hacía perder el equilibrio!).

      En la cima de la montaña

      A nivel de actividades dentro de la casa, se destaca jugamos varios tutes cabrero. Incluso Felipe aprendió a jugar, ¡¡y casi gana uno!! Yo tuve suerte, gané un par, y el último que jugamos lo gané yo solito, porque hice un capote cuando quedábamos sólo tres y estábamos al borde de salir.

      También chusmeamos mucho y nos entrometemos en la imprenta, donde Gus trata de trabajar normalmente mientras nosotros estamos visitando. Los chicos se entretienen anillando papelitos, a mí me fascina los automatismos de las máquinas, Moni acomoda e intercala facturas, etc. Pobre Gus.

      Los chicos también estuvieron ayudando un poco en la huerta, cosechando unas frutillas caseras (estaban asombrósamente ricas). No faltó un juego de tirarse agua con el regador entre Felu, Male y Gus...

      Almorzando sobre el Limay

      Unos pehuenes cerca de una montaña con forma rara, camino a Villa Pehuenia

      Un día nos lo tomamos y nos fuimos hasta el Chocón, con mi vieja.

      Visitamos nuevamente el museo de la ciudad, ya que los niños crecen y aprovechan otras cosas. Y a decir verdad, uno también aprende siempre algo nuevo con cada visita.

      Guarda que te come

      Fue una complicación almorzar. Fuimos al restaurant del camping (habíamos ido también dos años atrás y estaba bueno), y nos enteramos que tenían cerveza artesanal: buenísimo! Pero vimos que la carta era muy reducida. Decidimos quedarnos igual, pero a la hora de pedir sólo tenían sánguche de lomo ($250!!), ravioles, y alguna cosita más. O sea, nos tomamos las cervezas y jugos, y nos fuimos.

      Encontramos otro restaurant, que parecía supercheto pero igual entramos al predio: en la puerta, en el horario, decía: "abrimos cuando llegamos, cerramos cuando nos vamos". Ok, tenía ganas de dejarles notita de "me voy a dejar mi dinero en otro lado".

      Al final pasamos por un almacén, compramos material para sanguchitos, y almorzamos bajo unos arbolitos :)

      Con Felu visitándo la estatua del Águila, en Piedra del ídem

      También hicimos un paseo más largo, esta vez con Diana y Gus. Nos llegamos hasta Villa Pehuenia, donde hicimos noche y casi no paseamos. Visitamos el lago y tomamos unos mates ahí, y comimos rico en un lugarcito lindo.

      En el lago de Villa Pehuenia

      Al otro día bien temprano nos fuimos para Chile. Tuvimos una espera bárbara para cruzar: tres horas del lado argentino hasta que hicimos todos los trámites. Del lado chileno resolvimos todo en una hora (contando con que tuve que volver a las oficinas argentinas para que corrigieran un número).

      Estuvimos un par de días solamente, como para conocer algunos lugares y ver si da para una estadía más larga. Alquilamos una cabaña linda en Villarrica, alejada del centro. El centro de la ciudad es muy lindo, por donde paseamos bastante (hay una graaaaaaaan feria semiartesanal donde compramos cositas lindas para la casa), fuimos a comer, comprar cosas, etc. Había bastante gente.

      Alrmorzando en Temuco

      El volcán de Villarrica

      Uno de los días nos fuimos a Temuco, una ciudad bastante más grande, a unos 80km. Paseamos un rato también por el centro, compramos un par de cosas, almorzamos muy rico (en Vicuña Mackenna 530: unas muy buenas sopas, una de champignones y otra de camarones, y una espectacular lasaña de berenjenas, más una ensalada de verdes), y visitamos un museo mapuche.

      Al lado del museo mapuche, en el mismo predio pero al aire libre, había una feria medieval: gente enseñando esgrima con espadas, contando cuentos, vendiendo todo tipo de cosas estilo medieval (ropas, armas, libros, lo que se te ocurra).

      Felipe en una plaza de Temuco

      Felipe flasheó cuando entró a la feria y vio a una chica con orejas tipo elfo, :), aunque también nos colgamos en la clase de esgrima, y en otro lugar donde había un "duende del bosque" contando un cuento con acertijos.

      Al volver a Argentina, del lado de Chile nos hicieron problema porque faltaba un sello (de algo del auto) en los papeles de la entrada al país. Nos faltaba a nosotros, a Gus y Diana, y a otra persona que estaba después en la cola. Se ve que le pifiaron o se olvidaron cuando pasamos dos días atrás. En fin, protestamos un poco y listo, dieron el ok (?). Nosotros apuntábamos a tener 3 o 4 horas de cola del lado de Argentina, como pasó dos días antes cuando nosotros hicimos el camino inverso, ¡pero no había nadie! Se ve que justo al ser domingo a la mañana, zafamos, resolvimos todo en media hora y nos fuimos para Aluminé.

      Moni y Male en Aluminé

      En Aluminé teníamos reservadas dos habitaciones en un hostal que resultó ser bárbaro (Diana y Gus ya lo conocían). Las habitaciones eran lindas, el desayuno casero, pero lo mejor era el parque y las parrillas, y un quincho totalmente comunal (con parrilla interna, heladera, horno, hornallas, microondas y muchas mesas).

      Al otro día de llegar hicimos rafting, lo que resultó toda una experiencia!  Felu remó un poco y todo, Male iba en el medio y se asustó un toque al romper los rápidos; igual en la mitad del paseo ellos dos se metieron en el rio, conmigo, Diana y Gus. Eso sí, el agua estaba muy fria, por suerte el guia (que era un capo, nos iba contando cosas del rio o de la naturaleza de la región) le prestó una remera a Malena y otra (la propia!) a Felipe, para que no tomaran frío mojados.

      Atacándo el rápido

      Felu experimentado remador

      Luego del rafting en sí nos quedamos disfrutando la tardecita en el rio, y nos volvimos que yo tenía que hacer unos pollos a la parrilla.

      Al otro día ya arrancamos la vuelta a Piedra del Águila, pero en el camino nos desviamos un poco para pasear por el Parque Nacional Lanin (aunque el volcán no se puedo ver mucho porque estaba muy nublado), y luego también fuimos a ver unas pinturas rupestres que casi ni quedaban luego de vandalismos por el humano estúpido.

      En Piedra estuvimos un día entero, y ya al siguiente partimos viaje a Buenos Aires, donde llegamos luego de hacer noche en Catriló.

      En la cima, buscando las pinturas rupestres

      Los pimpollos en el lago de Villa Pehuenia

      Unas vacaciones bárbaras. Muchas fotos acá.

      Read more
      Stéphane Graber

      LXD logo

      LXD on other operating systems?

      While LXD and especially its API have been designed in a mostly OS-agnostic way, the only OS supported for the daemon right now is Linux (and a rather recent Linux at that).

      However since all the communications between the client and daemon happen over a REST API, there is no reason why our default client wouldn’t work on other operating systems.

      And it does. We in fact gate changes to the client on having it build and pass unit tests on Linux, Windows and MacOS.

      This means that you can run one or more LXD daemons on Linux systems on your network and then interact with those remotely from any Linux, Windows or MacOS machine.

      Setting up your LXD daemon

      We’ll be connecting to the LXD daemon over the network, so you’ll need to make sure it’s listening and has a password configured so that new clients can add themselves to the trust store.

      This can be done with:

      lxc config set core.https_address "[::]:8443"
      lxc config set core.trust_password "my-password"

      In my case, that remote LXD can be reached with “djanet.maas.mtl.stgraber.net”, you’ll want to replace that with your LXD server’s FQDN or IP in the commands used below.

      Windows client

      Pre-built native binaries

      Our Windows CI service builds a tarball for every commit. You can grab the latest one here:
      https://ci.appveyor.com/project/lxc/lxd/branch/master/artifacts

      Then unpack the archive and open a command prompt in the directory where you unpacked the lxc.exe binary.

      Build from source

      Alternatively, you can build it from source, by first installing Go using the latest MSI based installer from https://golang.org/dl/ and then Git from https://git-scm.com/downloads.

      And then in a command prompt, run:

      git config --global http.https://gopkg.in.followRedirects true
      go get -v -x github.com/lxc/lxd/lxc

      Use Ubuntu on Windows (“bash”)

      For this, you need to use Windows 10 and have the Windows subsystem for Linux enabled.
      With that done, start an Ubuntu shell by launching “bash”. And you’re done.
      The LXD client is installed by default in the Ubuntu 16.04 image.

      Interact with the remote server

      Regardless of which method you picked, you’ve now got access to the “lxc” command and can add your remote server.

      Using the native build does have a few restrictions to do with Windows terminal escape codes, breaking things like the arrow keys and password hiding. The Ubuntu on Windows way uses the Linux version of the LXD client and so doesn’t suffer from those limitations.

      MacOS client

      Even though we do have MacOS CI through Travis, they don’t host artifacts for us and so don’t have prebuilt binaries for people to download.

      Build from source

      Similarly to the Windows instructions, you can build the LXD client from source, by first installing Go using the latest DMG based installer from https://golang.org/dl/ and then Git from https://git-scm.com/downloads.

      Once that’s done, open a new Terminal window and run:

      export GOPATH=~/go
      go get -v -x github.com/lxc/lxd/lxc
      sudo ln -s ~/go/bin/lxc /usr/local/bin/

      At which point you can use the “lxc” command.

      Conclusion

      The LXD client can be built on all the main operating systems and on just about every architecture, this makes it very easy for anyone to interact with existing LXD servers, whether they’re themselves using a Linux machine or not.

      Thanks to our pretty strict backward compatibility rules, the version of the client doesn’t really matter. Older clients can talk to newer servers and newer clients can talk to older servers. Obviously in both cases some features will not be available, but normal container worflow operations will work fine.

      Extra information

      The main LXD website is at: https://linuxcontainers.org/lxd
      Development happens on Github at: https://github.com/lxc/lxd
      Mailing-list support happens on: https://lists.linuxcontainers.org
      IRC support happens in: #lxcontainers on irc.freenode.net
      Try LXD online: https://linuxcontainers.org/lxd/try-it

      Read more
      UbuntuTouch

      我们知道对于python项目来说,我们只需要在我们的snapcraft.yaml中指定plugin为python它即可为python项目下载在snapcraft中指定的python的版本。但是对于有一些项目来说,我们的开发者可能需要一个特定的python的版本,那么我们怎么来实现这个功能呢?在今天的教程中,我们来介绍在snapcraft 2.27中所增添的一个新的功能。


      我们首先来看一下我做的一个项目:

      https://github.com/liu-xiao-guo/python-plugin

      snapcraft.yaml

      name: python36
      version: '0.1' 
      summary: This is a simple example not using python plugin
      description: |
        This is a python3 example
      
      grade: stable 
      confinement: strict
      
      apps:
        python36:
          command: helloworld_in_python
        python-version:
          command: python3 --version
      
      parts:
        my-python-app:
          source: https://github.com/liu-xiao-guo/python-helloworld.git
          plugin: python
          after: [python]
        python:
          source: https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tar.xz
          plugin: autotools
          configflags: [--prefix=/usr]
          build-packages: [libssl-dev]
          prime:
            - -usr/include

      在这里,针对我们的python项目,它指定了在我们项目python part中所定义的python。这个python的版本是直接从网上直接进行下载的。

      我们可以直接打包我们的应用,并并运行我们的应用:

      $ python36
      Hello, world

      显然我们的python是可以正常工作的。我们可以通过命令python36.python-version命令来检查我们的python的版本:

      $ python36.python-version 
      Python 3.6.0

      它显示了,我们目前正在运行的python的版本3.6。它就是我们在snapcraft中所下载的版本。
      作者:UbuntuTouch 发表于2017/2/20 9:23:30 原文链接
      阅读:97 评论:0 查看评论

      Read more
      UbuntuTouch

      在最新的snapd 2.20中,它开始支持一个叫做classic模式的snap 应用开发.这种classic可以使得我们的应用开发者能够快速地开发我们所需要的应用,这是因为我们不必要对我们的现有的应用做太多的改变.在classic模式下的应用,它可以看见host系统的所有的位于"/"下的文件,就像我们目前正常的应用一样.但是在安装我们的应用后,它的所有文件将位于/snap/foo/current下.它的执行文件将位于/snap/bin目录下,就像我们目前的所有其它的snap应用一样.

      当我们安装我们的classic模式下的snap应用时,我们需要使用--classic选项.在上传我们的应用到Ubuntu Core商店时,也需要人工检查.它可以看见位于/snap/core/current下的所有的文件,同时也可以对host里的任何位置的文件进行操作.这样做的目的是为了能够使得开发者快速地发布自己的以snap包为格式的应用,并在以后的开发中逐渐运用Ubuntu Core的confinement以得到完善.在目前看来,classic模式下的应用在可以遇见的将来不能够安装到all-snap系统中,比如Ubuntu Core 16.

      对于classic模式的应用来说,它的"/"目录对应于host系统的"/".更多的信息可以参阅地址:http://snapcraft.io/docs/reference/confinement


      安装

      在开发之前,我们在desktop上安装core而不是ubuntu-core.我们可以用snap list命令来查看:

      liuxg@liuxg:~$ snap list
      Name          Version  Rev  Developer  Notes
      core          16.04.1  714  canonical  -
      firefox-snap  0.1      x1              classic
      hello         1.0      x1              devmode
      hello-world   6.3      27   canonical  -
      

      如果你的系统里是安装的ubuntu-core的话,建议大家使用devtool中的reset-state来使得我们的系统恢复到最初的状态(没有任何安装的snap).在以后的snapd发布中,我们将不再有ubuntu-core这个snap了.我们也可以适用如下的方法来删除ubuntu-core snap并安装上core snap:

      $ sudo apt purge -y snapd
      $ sudo apt install snapd
      $ sudo snap install core

      另外对于有的开发者来说从stable channel得不到最新的snap 2.20,我们可以在我们的Ubuntu Destkop中,打开"System Settings"/"Software & Updates"/"Developer Options":


      我们可以打开上面所示的开关,就可以得到最新的所有关于我们Ubuntu桌面系统的发布的软件.snap 2.20版本目前就在这个xenial-proposed之中.

      在今天的教程中,我们来做一个例程来进行将讲解:

      https://github.com/liu-xiao-guo/helloworld-classic

      在上面的例程中,它的snapcraft.yaml的文件如下:

      snapcraft.yaml

      name: hello
      version: "1.0"
      summary: The 'hello-world' of snaps
      description: |
          This is a simple snap example that includes a few interesting binaries
          to demonstrate snaps and their confinement.
          * hello-world.env  - dump the env of commands run inside app sandbox
          * hello-world.evil - show how snappy sandboxes binaries
          * hello-world.sh   - enter interactive shell that runs in app sandbox
          * hello-world      - simply output text
      grade: stable
      confinement: classic
      type: app  #it can be gadget or framework
      
      apps:
       env:
         command: bin/env
       evil:
         command: bin/evil
       sh:
         command: bin/sh
       hello-world:
         command: bin/echo
       createfile:
         command: bin/createfile
       createfiletohome:
         command: bin/createfiletohome
       listhome:
         command: bin/listhome
       showroot:
         command: bin/showroot
      
      parts:
       hello:
        plugin: dump
        source: .    

      从上面的例程中,我们可以看出来,我们在confinement的位置定义为:

      confinement: classic

      这定义了我们的这个snap应用是一个classic的应用.我们安装时也必须使用--classic的选项来进行安装.细心的开发者会发现,在我们的应用中,我们没有定义任何的plug,也就是我们没有使用任何的interface.大家可以和我们的另外一个项目https://github.com/liu-xiao-guo/helloworld-demo进行比较一下.

      就像我们之前所说的,我们只希望能尽快把我们的应用以snap形式发布,在classic模式下,我们暂时不考虑安全的问题.

      我们可以打包我们的应用,并以如下的命令来进行安装:

      $ sudo snap install hello_1.0_amd64.snap --classic --dangerous
      

      我们的脚本showroot内容如下:

      #!/bin/bash
      
      cd /
      echo "list all of the content in the root:"
      ls
      
      echo "show the home content:"
      cd home
      ls
      

      当我们运行我们的应用showroot时,我们可以看到:

      liuxg@liuxg:~/snappy/desktop/helloworld-classic$ hello.showroot 
      list all of the content in the root:
      bin    core  home	     lib	 media	proc  sbin  sys  var
      boot   dev   initrd.img      lib64	 mnt	root  snap  tmp  vmlinuz
      cdrom  etc   initrd.img.old  lost+found  opt	run   srv   usr  vmlinuz.old
      show the home content:
      liuxg  root.ini
      liuxg@liuxg:~/snappy/desktop/helloworld-classic$ ls /
      bin    core  home            lib         media  proc  sbin  sys  var
      boot   dev   initrd.img      lib64       mnt    root  snap  tmp  vmlinuz
      cdrom  etc   initrd.img.old  lost+found  opt    run   srv   usr  vmlinuz.old
      

      显然,它可以看到我们整个host系统的文件目录.这个应用时间上可以对它所看到的文件及目录进行操作.
      当然,我们也可以运行evil脚本:

      #!/bin/sh
      
      set -e
      echo "Hello Evil World!"
      
      echo "This example demonstrates the app confinement"
      echo "You should see a permission denied error next"
      
      echo "Haha" > /var/tmp/myevil.txt
      
      echo "If you see this line the confinement is not working correctly, please file a bug"
      
      运行结果如下:

      liuxg@liuxg:~/snappy/desktop/helloworld-classic$ hello.evil
      Hello Evil World!
      This example demonstrates the app confinement
      You should see a permission denied error next
      If you see this line the confinement is not working correctly, please file a bug
      

      显然在我们没有使用interface的情况下,我们可以想其它的任何目录进行操作,并写入我们想要的数据.confinement在classic模式下不起任何的作用.对于我们开发者来说,我们只需要快速地把我的应用打包为snap即可.

      最后,作为一个速成的例子,我们通过classic模式来快速地把Firefox打包为一个snap:

      Firefox snapcraft.yaml

      name: firefox-snap
      version: '0.1'
      summary: "A Firefox snap"
      description: "Firefox in a classic confined snap"
      
      grade: devel
      confinement: classic
      
      apps:
        firefox-snap:
          command: firefox
          aliases: [firefox]
      
      parts:
        firefox:
          plugin: dump
          source: https://download.mozilla.org/?product=firefox-50.1.0-SSL&os=linux64&lang=en-US
          source-type: tar

      在这里,我们直接下载我们需要的版本,并进行打包.安装并运行我们的Firefox应用:



      整个项目的源码在地址:https://github.com/liu-xiao-guo/firefox-snap





      作者:UbuntuTouch 发表于2017/1/6 13:48:04 原文链接
      阅读:358 评论:2 查看评论

      Read more
      UbuntuTouch

      我们知道在一个snap包里,我们可以定义任何数量的app.针对desktop应用来说,那么我们如何使得我们的每个应用都有自己的icon及desktop文件呢?在今天的文章中,我们将介绍如何实现这个.特别注意的是,这个新的feature只有在snapcraft 2.25+版本中才可以有.


      首先,我们来看一下我已经做好的一个项目:

      https://github.com/liu-xiao-guo/helloworld-desktop

      整个应用的文件架构如下:

      liuxg@liuxg:~/snappy/desktop/helloworld-desktop$ tree -L 3
      .
      ├── bin
      │   ├── createfile
      │   ├── createfiletohome
      │   ├── echo
      │   ├── env
      │   ├── evil
      │   ├── sh
      │   └── writetocommon
      ├── echo.desktop
      ├── README.md
      ├── setup
      │   └── gui
      │       ├── echo.png
      │       ├── helloworld.desktop
      │       └── helloworld.png
      └── snapcraft.yaml

      从上面我们可以看出来,我们已经有一个叫做setup/gui的目录.它里面包含了一个叫做helloworld.desktop的文件:

      helloworld.desktop

      [Desktop Entry]
      Type=Application
      Name=Hello
      GenericName=Hello world
      Comment=A hello world Ubuntu Desktop
      Keywords=hello;world;
      Exec=hello-xiaoguo.env
      Icon=${SNAP}/meta/gui/helloworld.png
      Terminal=true
      X-Ubuntu-Touch=false
      X-Ubuntu-Default-Department-ID=accessories
      X-Ubuntu-Splash-Color=#F5F5F5
      StartupNotify=true

      在这里它指定了这个应用的icon及执行的脚本hello-xiaoguo.env.

      我们再来看看我们的snapcraft.yaml文件:

      snapcraft.yaml

      name: hello-xiaoguo
      version: "1.0"
      summary: The 'hello-world' of snaps
      description: |
          This is a simple snap example that includes a few interesting binaries
          to demonstrate snaps and their confinement.
          * hello-world.env  - dump the env of commands run inside app sandbox
          * hello-world.evil - show how snappy sandboxes binaries
          * hello-world.sh   - enter interactive shell that runs in app sandbox
          * hello-world      - simply output text
      grade: stable
      confinement: strict
      type: app  #it can be gadget or framework
      
      apps:
       env:
         command: bin/env
       evil:
         command: bin/evil
       sh:
         command: bin/sh
       hello-world:
         command: bin/echo
         desktop: usr/share/applications/echo.desktop
       createfile:
         command: bin/createfile
       createfiletohome:
         command: bin/createfiletohome
       writetocommon:
         command: bin/writetocommon
      
      plugs:
          home:
              interface: home
      
      parts:
       hello:
        plugin: dump
        source: .
        organize:
          echo.desktop: usr/share/applications/echo.desktop

      在这个文件中,我们也定义了其它的应用,比如hello-world.那么我们如何为它也定义自己的desktop文件呢?答案是:

       hello-world:
         command: bin/echo
         desktop: usr/share/applications/echo.desktop

      我们可以在它的command下面指定一个属于自己的desktop文件.在这里我们的echo.desktop文件如下:

      echo.desktop

      [Desktop Entry]
      Type=Application
      Name=Echo
      GenericName=Hello world
      Comment=A hello world Ubuntu Desktop
      Keywords=hello;world;
      Exec=hello-xiaoguo.hello-world
      Icon=${SNAP}/meta/gui/echo.png
      Terminal=true
      X-Ubuntu-Touch=false
      X-Ubuntu-Default-Department-ID=accessories
      X-Ubuntu-Splash-Color=#F5F5F5
      StartupNotify=true

      在这里它指定了自己的执行文件及一个属于自己的icon.我们打包我们的应用,并安装.在Ubuntu Desktop的dash中,我们可以看到:



      运行"Hello World"应用显示:



      运行我们的"echo"应用:








      作者:UbuntuTouch 发表于2017/1/23 10:43:39 原文链接
      阅读:229 评论:0 查看评论

      Read more
      UbuntuTouch

      在很多的时候,我们想把一个website变为一个snap应用,从而我们可以直接从商店里进行下载它,并直接使用.我们不需要在浏览器中输入这个网站的地址.也有很多的时候,我们的游戏就在一个网站上,比如http://hexgl.bkcore.com/play/,我们可以直接把该网址打包进我们的snap应用,从而使得它直接可以从商店下载并运行.在今天的教程中,我们来展示如何把网址的url打包到我们的应用中.

      为了说明问题方便,我们使用www.sina.com.cn来进行展示:

      snapcraft.yaml


      name: sina-webapp
      version: '1.0'
      summary: Sina webapp
      description: |
        Webapp version of the Sina web application.
      
      grade: stable
      confinement: strict
      
      apps:
        sina-webapp:
          command: webapp-launcher --enable-back-forward --webappUrlPatterns=http?://www.sina.com/* http://www.sina.com/ %u
          plugs:
            - browser-sandbox
            - camera
            - network
            - network-bind
            - opengl
            - pulseaudio
            - screen-inhibit-control
            - unity7
            - network-control
            - mount-observe
      
      plugs:
        browser-sandbox:
          interface: browser-support
          allow-sandbox: false
        platform:
          interface: content
          content: ubuntu-app-platform1
          target: ubuntu-app-platform
          default-provider: ubuntu-app-platform
      
      parts:
        webapp-container:
          after: [desktop-ubuntu-app-platform,webapp-helper]
          stage-packages:
            - fonts-wqy-zenhei
            - fcitx-frontend-qt5
          plugin: nil

      在这里,我们使用里desktop-ubuntu-app-platform cloud part.注意在这里,我们也加入了对中文字体及输入法的支持:

            - fonts-wqy-zenhei
            - fcitx-frontend-qt5

      我们可以参考我先前的文章"利用ubuntu-app-platform提供的platform接口来减小Qt应用大小"来安装并使用ubuntu-app-platform:platform.具体来说,我们必须进行如下的安装:

      $ sudo snap install ubuntu-app-platform

      我们在terminal中打入:
      $ snapcraft
      就可以把我们的应用打包为snap格式.我们使用如下的命令来进行安装:
      $ sudo snap install sina-webapp_1.0_amd64.snap --dangerous
      等我们安装好后,我们可以发现:

      liuxg@liuxg:~$ snap list
      Name                 Version  Rev  Developer  Notes
      amazon-webapp        1.3      x1              -
      azure                0.1      x2              -
      core                 16.04.1  714  canonical  -
      hello-world          6.3      27   canonical  -
      sina-webapp          1.0      x1              -
      snappy-debug         0.26     25   canonical  -
      ubuntu-app-platform  1        22   canonical  -
      

      我们的sian-webapp已经被成功安装好了.在这里面,我们也可以发现ubuntu-app-platform及core两个snap应用.在我们的应用中,由于我们定义了如下的plug:
      • camera
      • mount-observe
      • network-control
      • content
      根据在网址http://snapcraft.io/docs/reference/interfaces里的介绍,我们发现这些接口必须是手动连接的,所以我们必须使用如下的命令:

      $ sudo snap connect sina-webapp:platform ubuntu-app-platform:platform
      $ sudo snap connect sina-webapp:camera core:camera
      $ sudo snap connect sina-webapp:network-control core:network-control
      $ sudo snap connect sina-webapp:mount-observe core:mount-observe

      通过上面的命令,我们进行了手动的连接.如果由于我们重新安装或其它原因在我们运行我们的应用时出现诸如:

      You need to connect the ubuntu-app-platform package with your application   
      to reuse shared assets, please run:  
      snap install ubuntu-app-platform  
      snap connect sina-webapp:platform ubuntu-app-platform:platform  

      这样的错误信息,我们需要使用如下的工具:
      $ sudo /usr/lib/snapd/snap-discard-ns sina-webapp  
      来清除先前的设置,然后在重新运行我们的应用之前,我们再手动连接我们上面所列出来的接口.

      我们可以在我们的Desktop的dash中找到我们的应用的图标,并运行.





      整个项目的源码在:https://github.com/liu-xiao-guo/sina-webapp.我们可以使用如下的命令从商店来下载这个应用:

      $ sudo snap install sina-webapp --beta




      作者:UbuntuTouch 发表于2017/1/22 14:09:32 原文链接
      阅读:286 评论:0 查看评论

      Read more
      UbuntuTouch

      [原]如何提高编译snap应用的速度

      在我们编译打包snap应用时,我们时常会发现在我们的代码或snapcraft.yaml中每次做一次小的改动后,重新运行snapcraft命令时,都会从Ubuntu archive中重新下载所需要的包.如果一个包很大的话,这需要很长的时间才可以完成.如果是在Desktop的情况下,我们有时可以使用VPN来解决这个问题.这种情况特别是发生在我们需要使用ARM板子进行编译打包的时候,因为我在这些板子上甚至不能运行VPN.那么我们如何来解决这个问题呢?

      很幸运的是,我们的同事ogra帮我们设计了一个叫做packageproxy的snap包.我们可以通过如下的命令来安装:

      $ sudo snap install packageproxy
      

      安装完后,我们可以通过snap list来发现:

      liu-xiao-guo@localhost:~$ snap list
      Name            Version       Rev  Developer  Notes
      classic         16.04         17   canonical  devmode
      core            16.04.1       716  canonical  -
      grovepi-server  1.0           x1              devmode
      packageproxy    0.1           3    ogra       -
      pi2             16.04-0.17    29   canonical  -
      pi2-kernel      4.4.0-1030-3  22   canonical  -

      在我们的ARM板子,比如树莓派中,我们通过安装classic应用,进入到classic的环境中:

      $ sudo snap install classic --devmode --edge
      $ sudo classic

      当然具体的步骤,我们可以参照文章"如何为树莓派安装Ubuntu Core并在Snap系统中进行编译".在进入到我们的classic环境后,我们需要多/etc/apt中的sources.list文件进行修改.为了保险起见,我们首先可以通过如下的命令来保存原先的sources.list文件

      (classic)liu-xiao-guo@localhost:/etc/apt$ sudo cp sources.list sources.list.bak
      

      这样以前的文件被保存于sources.list.bak文件中.如果我们打开sources.list文件,我们可以看见它的内容如下:

      sources.list

      # See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
      # newer versions of the distribution.
      deb http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted
      # deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted
      
      ## Major bug fix updates produced after the final release of the
      ## distribution.
      deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted
      # deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted
      
      ## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
      ## team. Also, please note that software in universe WILL NOT receive any
      ## review or updates from the Ubuntu security team.
      deb http://ports.ubuntu.com/ubuntu-ports/ xenial universe
      # deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial universe
      deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates universe
      # deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates universe
      
      ## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
      ## team, and may not be under a free licence. Please satisfy yourself as to
      ## your rights to use the software. Also, please note that software in
      ## multiverse WILL NOT receive any review or updates from the Ubuntu
      ## security team.
      deb http://ports.ubuntu.com/ubuntu-ports/ xenial multiverse
      # deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial multiverse
      deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates multiverse
      # deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates multiverse
      
      ## N.B. software from this repository may not have been tested as
      ## extensively as that contained in the main release, although it includes
      ## newer versions of some applications which may provide useful features.
      ## Also, please note that software in backports WILL NOT receive any review
      ## or updates from the Ubuntu security team.
      deb http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted universe multiverse
      # deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted universe multiverse
      
      ## Uncomment the following two lines to add software from Canonical's
      ## 'partner' repository.
      ## This software is not part of Ubuntu, but is offered by Canonical and the
      ## respective vendors as a service to Ubuntu users.
      # deb http://archive.canonical.com/ubuntu xenial partner
      # deb-src http://archive.canonical.com/ubuntu xenial partner
      
      deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted
      # deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted
      deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security universe
      # deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security universe
      deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security multiverse
      # deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security multiverse
      

      显然,在上面的文件中,所有的源都指向http://ports.ubuntu.com/ubuntu-ports/.也就是说每次我们重新编译我们的snap应用时,它都会从上面的地址进行下载.如果一个包很大的话,它就会造成我们的编译的时间过长.这显然不是我们所期望的.如果,我们把上面的http://ports.ubuntu.com/ubuntu-ports/换成http://localhost:9999/ubuntu-ports/,那么整个sources.list文件的内容如下:

      sources.list

      # See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
      # newer versions of the distribution.
      deb http://localhost:9999/ubuntu-ports/ xenial main restricted
      # deb-src http://localhost:9999/ubuntu-ports/ xenial main restricted
      
      ## Major bug fix updates produced after the final release of the
      ## distribution.
      deb http://localhost:9999/ubuntu-ports/ xenial-updates main restricted
      # deb-src http://localhost:9999/ubuntu-ports/ xenial-updates main restricted
      
      ## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
      ## team. Also, please note that software in universe WILL NOT receive any
      ## review or updates from the Ubuntu security team.
      deb http://localhost:9999/ubuntu-ports/ xenial universe
      # deb-src http://localhost:9999/ubuntu-ports/ xenial universe
      deb http://localhost:9999/ubuntu-ports/ xenial-updates universe
      # deb-src http://localhost:9999/ubuntu-ports/ xenial-updates universe
      
      ## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
      ## team, and may not be under a free licence. Please satisfy yourself as to
      ## your rights to use the software. Also, please note that software in
      ## multiverse WILL NOT receive any review or updates from the Ubuntu
      ## security team.
      deb http://localhost:9999/ubuntu-ports/ xenial multiverse
      # deb-src http://localhost:9999/ubuntu-ports/ xenial multiverse
      deb http://localhost:9999/ubuntu-ports/ xenial-updates multiverse
      # deb-src http://localhost:9999/ubuntu-ports/ xenial-updates multiverse
      
      ## N.B. software from this repository may not have been tested as
      ## extensively as that contained in the main release, although it includes
      ## newer versions of some applications which may provide useful features.
      ## Also, please note that software in backports WILL NOT receive any review
      ## or updates from the Ubuntu security team.
      deb http://localhost:9999/ubuntu-ports/ xenial-backports main restricted universe multiverse
      # deb-src http://localhost:9999/ubuntu-ports/ xenial-backports main restricted universe multiverse
      
      ## Uncomment the following two lines to add software from Canonical's
      ## 'partner' repository.
      ## This software is not part of Ubuntu, but is offered by Canonical and the
      ## respective vendors as a service to Ubuntu users.
      # deb http://archive.canonical.com/ubuntu xenial partner
      # deb-src http://archive.canonical.com/ubuntu xenial partner
      
      deb http://localhost:9999/ubuntu-ports/ xenial-security main restricted
      # deb-src http://localhost:9999/ubuntu-ports/ xenial-security main restricted
      deb http://localhost:9999/ubuntu-ports/ xenial-security universe
      # deb-src http://localhost:9999/ubuntu-ports/ xenial-security universe
      deb http://localhost:9999/ubuntu-ports/ xenial-security multiverse
      # deb-src http://localhost:9999/ubuntu-ports/ xenial-security multiverse

      也就是说,每当我们重新下载我们的包的时候,它将从我们的本地地址http://localhost:9999/ubuntu-ports/进行下载.
      • 如果这个包曾经被下载过,那么packageproxy将帮我们从本地的cache中直接提取,从而不需要重新下载
      • 如果这个包从来没有被现在过,那么packageproxy将帮助我们从网上进行下载,并保存于本地以备以后重复使用
      为了能够在命令行中进行修改sources.list文件,我们可以使用如下的命令:

      sudo sed -i 's/http:\/\/ports.ubuntu.com\/ubuntu-ports/http:\/\/localhost:9999\/ubuntu-ports/g' /etc/apt/sources.list

      这显然是一种非常好的方法.在第一编译的时候,它可能需要一些时间.但是以后的编译,它可以直接从本地提取从而加速我们的编译的速度.
      在我们设置完上面的步骤后,我们可以通过如下的命令来进行系统的更新及安装:

      $ sudo apt-get update
      $ sudo apt install snapcraft git-core build-essential

      这样我们就安装好我们的编译的环境了.通过这样的配置过后,在第一次编译我的应用时,如果需要的包从来没有下载过,就会慢一些.第二次编译我们的应用时,就会发现速度快很多.当然,我们可以把我们的地址指向某一个设备的IP地址,而不使用localhost,从而使大家从同一个设备中提取所需要的包.这种方法适合于网路环境比较差的时候.特别适合一些hackathon活动.作为一个展示的例子http://paste.ubuntu.com/23789982/,我们可以看到在clean项目后,编译的速度大大提高了.

      如果在使用过程中,出现如下的错误:

      (classic)liu-xiao-guo@localhost:~$ sudo apt-get update
      Err:1 http://localhost:9999/ubuntu-ports xenial InRelease
        Could not connect to localhost:9999 (127.0.0.1). - connect (111: Connection refused) [IP: 127.0.0.1 9999]
      Err:2 http://localhost:9999/ubuntu-ports xenial-updates InRelease
        Unable to connect to localhost:9999: [IP: 127.0.0.1 9999]
      Err:3 http://localhost:9999/ubuntu-ports xenial-backports InRelease
        Unable to connect to localhost:9999: [IP: 127.0.0.1 9999]
      Err:4 http://localhost:9999/ubuntu-ports xenial-security InRelease
        Unable to connect to localhost:9999: [IP: 127.0.0.1 9999]

      这种情况可能是由于packageproxy在运行时出现一些问题,我们可以通过删除在如下地址下的文件来解决:

      liu-xiao-guo@localhost:/var/snap/packageproxy/3$ ls
      approx.conf  config.yaml  hosts.allow  hosts.deny  lockfile.lock  var

      我们可以删除上面的lockfile.lock来解决这个问题.

      另外,这种方法也适合在Ubuntu Desktop下的snap编译打包,我们只需要把上面的"ubuntu-ports"修改为"ubuntu"即可.这个练习就留给开发者.

      如果大家想删除所有已经下载的包以减少存储空间:

      • 使用snap remove packageproxy命令来删除这个应用
      • 删除rm -rf /var/snap/packageproxy/3/var/cache/approx/*所有的文件









      作者:UbuntuTouch 发表于2017/1/13 10:04:38 原文链接
      阅读:538 评论:4 查看评论

      Read more
      UbuntuTouch

      Socket.io可以使得我们的服务器和客户端进行双向的实时的数据交流。它比HTTP来说更具有传输数据量少的优点。同样地,websocket也具有同样的优点。你可以轻松地把你的数据发送到服务器,并收到以事件为驱动的响应,而不用去查询。在今天的教程中,我们来讲一下如何利用socket.io和websocket来做一个双向的通讯。


      1)创建一个socket.io的服务器


      首先我们先看一下我完成的一个项目:


      我们首先看一下我们的snapcraft.yaml文件:

      snapcraft.yaml

      name: socketio
      version: "0.1"
      summary: A simple shows how to make use of socket io
      description: socket.io snap example
      
      grade: stable
      confinement: strict
      
      apps:
        socket:
          command: bin/socketio
          daemon: simple
          plugs: [network-bind]
      
      parts:
        nod:
          plugin: nodejs
          source: .
         

      这是一个nodejs的项目。我们使用了nodejs的plugin。我们的package.json文件如下:

      package.json

      {
        "name": "socketio",
        "version": "0.0.1",
        "description": "Intended as a nodejs app in a snap",
        "license": "GPL-3.0",
        "author": "xiaoguo, liu",
        "private": true,
        "bin": "./app.js",
        "dependencies": {
          "express": "^4.10.2",
          "nodejs-websocket": "^1.7.1",
          "socket.io": "^1.3.7"
        }
      }
      

      由于我们需要使用到webserver,所有我们安装了express架构包。另外,我们使用到socket.io及websocket,所有,我们把这些包都打入到我们的snap包中。

      再来看看我们的应用app.js的设计:

      app.js

      #!/usr/bin/env node
      
      var express = require('express');
      var app = require('express')();
      var http = require('http').Server(app);
      var io = require('socket.io')(http);	
      
      app.get('/', function(req, res){
         res.sendFile(__dirname + '/www/index.html');
      });
      
      app.use(express.static(__dirname + '/www'));
      
      //Whenever someone connects this gets executed
      io.on('connection', function(socket){
        console.log('A user connected');
        
        setInterval(function(){
      	  var value = Math.floor((Math.random() * 1000) + 1);
      	  io.emit('light-sensor-value', '' + value);
      	  // console.log("value: " + value)
      	  
      	  // This is another way to send data
      	  socket.send(value);
        }, 2000); 
      
        //Whenever someone disconnects this piece of code executed
        socket.on('disconnect', function () {
          console.log('A user disconnected');
        });
      
      });
      
      http.listen(4000, function(){
        console.log('listening on *:4000');
      });
      
      var ws = require("nodejs-websocket")
      
      console.log("Going to create the server")
      
      String.prototype.format = function() {
          var formatted = this;
          for (var i = 0; i < arguments.length; i++) {
              var regexp = new RegExp('\\{'+i+'\\}', 'gi');
              formatted = formatted.replace(regexp, arguments[i]);
          }
          return formatted;
      };
       
      // Scream server example: "hi" -> "HI!!!" 
      var server = ws.createServer(function (conn) {
      	
          console.log("New connection")
      	var connected = true;
          
          conn.on("text", function (str) {
              console.log("Received "+str)
              conn.sendText(str.toUpperCase()+"!!!")
          })
          
          conn.on("close", function (code, reason) {
              console.log("Connection closed")
              connected = false
          })
              	
        setInterval(function(){
      	  var value = Math.floor((Math.random() * 1000) + 1);
      	  var data = '{"data":"{0}"}'.format(value)
      	  if (connected){
      		conn.send(data);
      	  }
        }, 2000); 	
      }).listen(4001)
      

      在代码的第一部分,我们创建了一个webserver,它使用的端口地址是4000。我们也同时启动了socket.io服务器,等待客户端的连接。一旦有一个连接的话,我们使用如下的代码每过一段时间来发送一些数据:

      //Whenever someone connects this gets executed
      io.on('connection', function(socket){
        console.log('A user connected');
        
        setInterval(function(){
      	  var value = Math.floor((Math.random() * 1000) + 1);
      	  io.emit('light-sensor-value', '' + value);
      	  // console.log("value: " + value)
      	  
      	  // This is another way to send data
      	  socket.send(value);
        }, 2000); 
      
        //Whenever someone disconnects this piece of code executed
        socket.on('disconnect', function () {
          console.log('A user disconnected');
        });
      
      });

      虽然这些数据是一些随机的,但是我们主要用来展示它是如何工作的。在实际的应用中,这些数据可以是从一些传感器中得到的。在我们的客户端中,我们可以打开webserver运行的地址:


      我们可以看到数据不断地进来,并在我们的客户端中显示出来。具体的设计请参考在www目录中的index.html文件。


      2)创建一个websocket的服务器


      在我们的app.js中,我们利用如下的代码来实现一个websocket的服务器。端口地址为4001。

      app.js


      var ws = require("nodejs-websocket")
      
      console.log("Going to create the server")
      
      String.prototype.format = function() {
          var formatted = this;
          for (var i = 0; i < arguments.length; i++) {
              var regexp = new RegExp('\\{'+i+'\\}', 'gi');
              formatted = formatted.replace(regexp, arguments[i]);
          }
          return formatted;
      };
       
      // Scream server example: "hi" -> "HI!!!" 
      var server = ws.createServer(function (conn) {
      	
          console.log("New connection")
      	var connected = true;
          
          conn.on("text", function (str) {
              console.log("Received "+str)
              conn.sendText(str.toUpperCase()+"!!!")
          })
          
          conn.on("close", function (code, reason) {
              console.log("Connection closed")
              connected = false
          })
              	
        setInterval(function(){
      	  var value = Math.floor((Math.random() * 1000) + 1);
      	  var data = '{"data":"{0}"}'.format(value)
      	  if (connected){
      		conn.send(data);
      	  }
        }, 2000); 	
      }).listen(4001)

      同样地,一旦有个连接,我们每隔两秒钟发送一个数据到我们的客户端。为了说明问题方便,我们设计了一个QML的客户端。

      Main.qml


      import QtQuick 2.4
      import Ubuntu.Components 1.3
      import Ubuntu.Components.Pickers 1.3
      import Qt.WebSockets 1.0
      import QtQuick.Layouts 1.1
      
      MainView {
          // objectName for functional testing purposes (autopilot-qt5)
          objectName: "mainView"
      
          // Note! applicationName needs to match the "name" field of the click manifest
          applicationName: "dialer.liu-xiao-guo"
      
          width: units.gu(60)
          height: units.gu(85)
      
          function interpreteData(data) {
              var json = JSON.parse(data)
              console.log("Websocket data: " + data)
      
              console.log("value: " + json.data)
              mainHand.value = json.data
          }
      
          WebSocket {
              id: socket
              url: input.text
              onTextMessageReceived: {
                  console.log("something is received!: " + message);
                  interpreteData(message)
              }
      
              onStatusChanged: {
                  if (socket.status == WebSocket.Error) {
                      console.log("Error: " + socket.errorString)
                  } else if (socket.status == WebSocket.Open) {
                      // socket.sendTextMessage("Hello World....")
                  } else if (socket.status == WebSocket.Closed) {
                  }
              }
              active: true
          }
      
          Page {
              header: PageHeader {
                  id: pageHeader
                  title: i18n.tr("dialer")
              }
      
              Item {
                  anchors {
                      top: pageHeader.bottom
                      left: parent.left
                      right: parent.right
                      bottom: parent.bottom
                  }
      
                  Column {
                      anchors.fill: parent
                      spacing: units.gu(1)
                      anchors.topMargin: units.gu(2)
      
                      Dialer {
                          id: dialer
                          size: units.gu(30)
                          minimumValue: 0
                          maximumValue: 1000
                          anchors.horizontalCenter: parent.horizontalCenter
      
                          DialerHand {
                              id: mainHand
                              onValueChanged: console.log(value)
                          }
                      }
      
      
                      TextField {
                          id: input
                          width: parent.width
                          text: "ws://192.168.1.106:4001"
                      }
      
                      Label {
                          id: value
                          text: mainHand.value
                      }
                  }
              }
          }
      }
      

      运行我们的服务器及客户端:



      我们可以看到我们数值在不断地变化。这个客户端的代码在:https://github.com/liu-xiao-guo/dialer

      在这篇文章中,我们展示了如何利用socket.io及websocket来进行双向的实时的通讯。在很多的物联网的应用中,我们可以充分利用这些通讯协议来更好地设计我们的应用。

      作者:UbuntuTouch 发表于2017/2/7 16:07:16 原文链接
      阅读:207 评论:3 查看评论

      Read more
      UbuntuTouch

      LXD作为一容器的hypervisor,它对LXC提供了更多的新的用户体验.在今天的教程中,我们来介绍如何利用LXD来在不同的Ubuntu Desktop版本下编译我们的snap应用.


      1)安装LXD及命令行工具


      我们可以参照链接来安装我们的LXD:https://linuxcontainers.org/lxd/getting-started-cli/.为了方便,我们可以利用已经做好的Ubuntu Image:

      liuxg@liuxg:~$ lxc launch ubuntu:yakkety
      Creating flying-snake
      Starting flying-snake

      在这里,我们创建了一个叫做flying-snake的容器.这个名字是自动生产的.它是基于Ubuntu 16.10的yakkety.
      如果你想有一个自己的容器的名称,你也可以使用如下的命令来生产:

      $ lxc launch ubuntu:yakkety foobar

      这里的foobar将是我们生成的容器的名称而不是像上面自动生成的flying-snake.

      我们可以利用如下的命令来查看:

      liuxg@liuxg:~$ lxc list
      +----------------------+---------+-------------------+------+------------+-----------+
      |         NAME         |  STATE  |       IPV4        | IPV6 |    TYPE    | SNAPSHOTS |
      +----------------------+---------+-------------------+------+------------+-----------+
      | flying-snake         | RUNNING | 10.0.1.143 (eth0) |      | PERSISTENT | 0         |
      +----------------------+---------+-------------------+------+------------+-----------+
      | immortal-feline      | STOPPED |                   |      | PERSISTENT | 0         |
      +----------------------+---------+-------------------+------+------------+-----------+
      | vivid-x86-armhf      | STOPPED |                   |      | PERSISTENT | 0         |
      +----------------------+---------+-------------------+------+------------+-----------+
      | xenial-desktop-amd64 | STOPPED |                   |      | PERSISTENT | 0         |
      +----------------------+---------+-------------------+------+------------+-----------+
      

      2)创建一个用户


      我们可以利用如下的命令来创建一个属于自己的用户:

      liuxg@liuxg:~$ lxc exec flying-snake -- adduser liuxg
      Adding user `liuxg' ...
      Adding new group `liuxg' (1001) ...
      Adding new user `liuxg' (1001) with group `liuxg' ...
      Creating home directory `/home/liuxg' ...
      Copying files from `/etc/skel' ...
      Enter new UNIX password: 
      Retype new UNIX password: 
      passwd: password updated successfully
      Changing the user information for liuxg
      Enter the new value, or press ENTER for the default
      	Full Name []: liuxg
      	Room Number []: 
      	Work Phone []: 
      	Home Phone []: 
      	Other []: 
      Is the information correct? [Y/n] y
      

      请注意这里的flying-snake为我们刚才创建的container的名称.开发者必须根据自己的名称进行选择.我为这个container创建了一个叫做liuxg的用户.为用户添加管理员权限:

      liuxg@liuxg:~$ lxc exec flying-snake -- adduser liuxg sudo
      Adding user `liuxg' to group `sudo' ...
      Adding user liuxg to group sudo
      Done.
      

      $ lxc exec flying-snake -- visudo
      通过上面的命令,启动编辑器,并在文件的最后,加入:

      <username>   ALL=(ALL) NOPASSWD: ALL
      



      注意这里的liuxg是我们刚才创建的用户名.开发者需要替换为自己的用户名.

      更新系统并安装所需要的工具:

      $ lxc exec flying-snake -- apt update -qq
      $ lxc exec flying-snake -- apt upgrade -qq
      $ lxc exec flying-snake -- apt install -qq -y snapcraft build-essential
      


      3)登陆并编译我们的应用


      我们可以通过如下的命令来登陆:

      $ lxc exec flying-snake -- sudo -iu liuxg

      注意这里的liuxg是我们之前创建的用户.

      liuxg@liuxg:~$ lxc exec flying-snake -- sudo -iu liuxg
      To run a command as administrator (user "root"), use "sudo <command>".
      See "man sudo_root" for details.
      
      liuxg@flying-snake:~$ 
      liuxg@flying-snake:~$ ls -al
      total 20
      drwxr-xr-x 2 liuxg liuxg 4096 Jan  4 02:52 .
      drwxr-xr-x 4 root  root  4096 Jan  4 02:52 ..
      -rw-r--r-- 1 liuxg liuxg  220 Jan  4 02:52 .bash_logout
      -rw-r--r-- 1 liuxg liuxg 3771 Jan  4 02:52 .bashrc
      -rw-r--r-- 1 liuxg liuxg  655 Jan  4 02:52 .profile
      liuxg@flying-snake:~$ mkdir apps
      liuxg@flying-snake:~$ cd apps/
      liuxg@flying-snake:~/apps$ git clone https://github.com/liu-xiao-guo/alias
      Cloning into 'alias'...
      remote: Counting objects: 4, done.
      remote: Compressing objects: 100% (4/4), done.
      remote: Total 4 (delta 0), reused 4 (delta 0), pack-reused 0
      Unpacking objects: 100% (4/4), done.
      Checking connectivity... done.
      liuxg@flying-snake:~/apps$ ls
      alias
      liuxg@flying-snake:~/apps$ cd alias/
      liuxg@flying-snake:~/apps/alias$ ls
      hello.sh  snapcraft.yaml
      liuxg@flying-snake:~/apps/alias$ snapcraft 
      Preparing to pull aliases 
      Pulling aliases 
      Preparing to build aliases 
      Building aliases 
      Staging aliases 
      Priming aliases 
      Snapping 'my-alias' |                                                                
      Snapped my-alias_0.1_amd64.snap

      我们可以看到我们已经在yakkety (16.10)的环境中把我们的应用打包为一个snap.

      我们可以利用 lxc file pull命令来把我们的容器里的文件拷入到我们的host:

      lxc file pull first/etc/hosts .
      我们可以利用:

      $ lxc stop flying-snake

      来停止我们的container.

      liuxg@liuxg:~/tmp$ lxc stop flying-snake
      liuxg@liuxg:~/tmp$ lxc list
      +----------------------+---------+------+------+------------+-----------+
      |         NAME         |  STATE  | IPV4 | IPV6 |    TYPE    | SNAPSHOTS |
      +----------------------+---------+------+------+------------+-----------+
      | flying-snake         | STOPPED |      |      | PERSISTENT | 0         |
      +----------------------+---------+------+------+------------+-----------+
      | immortal-feline      | STOPPED |      |      | PERSISTENT | 0         |
      +----------------------+---------+------+------+------------+-----------+
      | vivid-x86-armhf      | STOPPED |      |      | PERSISTENT | 0         |
      +----------------------+---------+------+------+------------+-----------+
      | xenial-desktop-amd64 | STOPPED |      |      | PERSISTENT | 0         |
      +----------------------+---------+------+------+------------+-----------+
      

      具体的操作可以参阅文章:https://linuxcontainers.org/lxd/getting-started-cli/








      作者:UbuntuTouch 发表于2017/1/4 11:50:37 原文链接
      阅读:464 评论:0 查看评论

      Read more
      UbuntuTouch

      [原]为自己的snap应用添加变量

      在很多snap应用开发的时候,我们可以使用我们自己的一个wrapper,并在这个wrapper中指定一些变量从而能够使得我们的应用能够正常地运行。这个特性也特别适合在移植有些snap应用中需要特别设定一些路径到我们snap应用的一些可读写目录中从而避免安全的问题。那么我们怎么实现这个功能呢?


      我们先来看一下我们做的一个例程:

      https://github.com/liu-xiao-guo/helloworld-env

      snapcraft.yaml

      name: hello
      version: "1.0"
      summary: The 'hello' of snaps
      description: |
          This is a simple snap example that includes a few interesting binaries
          to demonstrate snaps and their confinement.
          * hello-world.env  - dump the env of commands run inside app sandbox
      
      grade: stable
      confinement: strict
      type: app  #it can be gadget or framework
      icon: icon.png
      
      apps:
       env:
         command: bin/env
         environment:
           VAR1: $SNAP/share
           VAR2: "hello, the world"
       evil:
         command: bin/evil
       sh:
         command: bin/sh
      
      parts:
       hello:
        plugin: dump
        source: .

      在上面的例子中,在“env”命令中,我们添加了environment项。在它的里面,我们定义了两个环境变量:VAR1及VAR2。
      打包我们的应用,同时执行我们的命令“hello.env”。

      $ hello.env | grep VAR
      VAR1=$SNAP/share
      VAR2=hello, the world

      在这里,我们可以看出来我们在没有使用脚本的情况下,为我们的应用添加了两个环境变量VAR1及VAR2。


      作者:UbuntuTouch 发表于2017/2/20 10:33:47 原文链接
      阅读:65 评论:0 查看评论

      Read more
      UbuntuTouch

      在先前的文章"利用snapweb来管理我们的Ubuntu Core应用"中,我们可以看到有些应用可以显示一个自己独特的应用图标,而另外一些应用只显示一个缺省的Ubuntu Logo图标.这其中的原因是因为我们在snapcraft.yaml文件中缺少定义icon.


      我们来看一下我已经创建好的一个项目:

      https://github.com/liu-xiao-guo/helloworld-icon

      它的snapcraft.yaml的定义如下:

      snapcraft.yaml


      name: hello-icon
      version: "1.0"
      summary: The 'hello-world' of snaps
      description: |
          This is a simple snap example that includes a few interesting binaries
          to demonstrate snaps and their confinement.
          * hello-world.env  - dump the env of commands run inside app sandbox
          * hello-world.evil - show how snappy sandboxes binaries
          * hello-world.sh   - enter interactive shell that runs in app sandbox
          * hello-world      - simply output text
      grade: stable
      confinement: strict
      type: app  #it can be gadget or framework
      icon: icon.png
      
      apps:
       env:
         command: bin/env
       evil:
         command: bin/evil
       sh:
         command: bin/sh
      
      parts:
       hello:
        plugin: dump
        source: .

      在这里我们定义了:

      icon: icon.png

       

      在我们打包完我们的应用,并安装好它.我们重新打开snapweb来查看:



      在这里,我们可以看到最新的图标.通过这样的方法,我们可以为我们的snap应用创建一个属于自己的图标.


      作者:UbuntuTouch 发表于2017/2/6 9:02:57 原文链接
      阅读:195 评论:0 查看评论

      Read more
      UbuntuTouch

      对于有些snap应用来说,我们很希望在snap安装时能够运行我们的一段脚本来做一些我们想要做的事,比如创建一个文件夹等.那么我们如何能得到这个事件呢?在我们的先前的文章"如何为我们的Ubuntu Core应用进行设置"中,我们已经展示了如何设置我们的snap应用.在那里面的configure脚本在设置时会被调用.事实上,它在安装时也会被自动调用.下面,我们以如下的例子来说明:

      https://github.com/liu-xiao-guo/helloworld-install

      在上面的例子中,我们的configure脚本如下:

      configure

      #!/bin/sh
      
      echo "This is called during the installation!"
      exit 1

      这是一个非常简单的脚本程序.在我们的安装过程中,它返回的值是"1",表明它是失败的.那么这个应用将不被成功安装:

      liu-xiao-guo@localhost:~/apps/helloworld-install$ sudo snap install *.snap --dangerous
      error: cannot perform the following tasks:
      - Run configure hook of "hello-install" snap if present (This is called during the installation!)
      liu-xiao-guo@localhost:~/apps/helloworld-install$ snap list
      Name            Version       Rev  Developer  Notes
      classic         16.04         17   canonical  devmode
      core            16.04.1       716  canonical  -
      grovepi-server  1.0           x1              devmode
      packageproxy    0.1           3    ogra       -
      pi2             16.04-0.17    29   canonical  -
      pi2-kernel      4.4.0-1030-3  22   canonical  -
      snapweb         0.21.2        25   canonical  -

      显然通过上面的展示,helloworld-install没有被安装到我们的系统中去.
      如果我们把configure脚本修改为:

      configure

      #!/bin/sh
      
      echo "This is called during the installation!"
      exit 0

      这个脚本的返回值为"0",表明它的安装是成功的.

      liu-xiao-guo@localhost:~/apps/helloworld-install$ sudo snap install *.snap --dangerous
      hello-install 1.0 installed
      liu-xiao-guo@localhost:~/apps/helloworld-install$ snap list
      Name            Version       Rev  Developer  Notes
      classic         16.04         17   canonical  devmode
      core            16.04.1       716  canonical  -
      grovepi-server  1.0           x1              devmode
      hello-install   1.0           x1              -
      packageproxy    0.1           3    ogra       -
      pi2             16.04-0.17    29   canonical  -
      pi2-kernel      4.4.0-1030-3  22   canonical  -
      snapweb         0.21.2        25   canonical  -
      liu-xiao-guo@localhost:~/apps/helloworld-install$ vi /var/log/syslog
      liu-xiao-guo@localhost:~/apps/helloworld-install$ sudo vi /var/log/syslog
      

      我们可以在系统的/var/log/syslog中找到这个脚本运行时的输出:



      显然脚本在安装时有被正常运行.我们可以通过运行这样一个hook来对我们的应用做一些初始化,从而为接下来的应用的运行铺好基础.

      作者:UbuntuTouch 发表于2017/1/16 10:30:29 原文链接
      阅读:235 评论:0 查看评论

      Read more
      UbuntuTouch

      在先前的文章"如何为我们的Ubuntu Core应用进行设置 "中,我们通过copy plugin的方法把我们想要的congfigure文件拷入到我们所需要的目录中.具体的实现是这样的:

      snapcraft.yaml

      parts:  
       hello:  
        plugin: copy  
        files:  
          ./bin: bin  
       config:  
        plugin: dump  
        source: .  
        organize:  
          configure: meta/hooks/configure  

      由于在snapcraft 2.25版本以后,它提供了对hook的支持,所有,我们只需要要在我们的项目的根目录中建立一个叫做snap/hooks的目录,并把我们的configure文件拷入即可:

      liuxg@liuxg:~/snappy/desktop/helloworld-hook$ tree -L 4
      .
      ├── bin
      │   ├── createfile
      │   ├── createfiletohome
      │   ├── echo
      │   ├── env
      │   ├── evil
      │   └── sh
      ├── setup
      │   ├── gui
      │   │   ├── helloworld.desktop
      │   │   └── helloworld.png
      │   └── license.txt
      ├── snap
      │   └── hooks
      │       └── configure
      └── snapcraft.yaml

      有了这样的文件架构后,snapcraft会自动帮我们把configure文件考入到meta/hooks文件目录下.下面是我们的prime目录里的内容:

      liuxg@liuxg:~/snappy/desktop/helloworld-hook/prime$ tree -L 3
      .
      ├── bin
      │   ├── createfile
      │   ├── createfiletohome
      │   ├── echo
      │   ├── env
      │   ├── evil
      │   └── sh
      ├── command-createfiletohome.wrapper
      ├── command-createfile.wrapper
      ├── command-env.wrapper
      ├── command-evil.wrapper
      ├── command-hello-world.wrapper
      ├── command-sh.wrapper
      ├── meta
      │   ├── gui
      │   │   ├── helloworld.desktop
      │   │   └── helloworld.png
      │   ├── hooks
      │   │   └── configure
      │   └── snap.yaml
      └── snap
          └── hooks
              └── configure

      我们必须记住这个功能只是在snapcraft 2.25以上的版本中才有的.我们可以看到在meta/hooks/中有一个叫做configure的文件.

      我们安装好这个snap应用,并执行如下的命令:

      $ sudo snap set hello username=foo password=bar

      我们可以通过如下的命令来获得这个值:

      $ sudo snap get hello username
      foo
      

      显然,我们得到我们设置的值.整个源码在:https://github.com/liu-xiao-guo/helloworld-hook.另外一个例程也可以在我们的snapcraft项目中的hooks找到.

      更多阅读:https://github.com/snapcore/snapcraft/blob/master/docs/hooks.md.就想文章中介绍的那样,我们也可以利用另外一种方法来实现.具体的例子见pyhooks.这种方法的好处是可以使用python语言来进行设置.运行结果如下:

      liuxg@liuxg:~$ sudo snap set pyhooks fail=true
      error: cannot perform the following tasks:
      - Run configure hook of "pyhooks" snap (Failing as requested.)
      liuxg@liuxg:~$ sudo snap set pyhooks fail=false


      更多阅读:https://snapcraft.io/docs/build-snaps/hooks




      作者:UbuntuTouch 发表于2017/1/20 14:05:49 原文链接
      阅读:214 评论:0 查看评论

      Read more