Google Cloud: Managing Source Code with a Google Cloud Source Repository

Hai!

Pada jurnal ini saya ingin membahas salah satu fitur yang sangat powerful dan bermanfaat terutama untuk para developer dan para DevOps, yaitu Google Cloud Source Repository.

Seperti GitHub, Bitbucket, dan Jira, Google Cloud Source Repository digunakan untuk tempat para developer dalam sebuah tim untuk berkolaborasi, membangun sebuah kode yang sifatnya terpusat. Selain itu bisa juga untuk tracking code ketika ada bug. Fiturnya sangat banyak dan membantu seperti skalabilitas yang tinggi, private repos, dan fully-featured. Lebih lengkapnya bisa dibaca disini ya https://cloud.google.com/source-repositories.

Okay, mari kita praktik.

Pertama, pastikan Cloud Source Repositories API dalam keadaan aktif. Jika belum, bisa diaktifkan dengan masuk ke Navigation Menu > API & Services > Library dan cari dengan kata kunci source repo.

Kita coba buat repositori melalui cli ya. Buka cloud-shell dan misal nama repo nya adalah mygcp_repo maka perintahnya:

gcloud source repos create mygcp_repo

Bisa verifikasi dengan perintah:

gcloud source repos list

Verifikasi bisa juga melalui console. Buka Navigation Menu > Source Repositories.

Dan berikut tampilannya.

Kita bisa gunakan repo dan manage code melalui cli. Kita clone terlebih dahulu:

gcloud source repos cloud mygcp_repo
cd mygcp_repo
ls

Buat sebuah file, misal README.md:

echo "#Contoh Repository" > README.md
ls
cat README.md

Definisikan email dan username, commit dan push file ke repos.

git config --global user.email "misskecup.bung@gmail.com"
git config --global user.name "misskecup_bung"
git add README.md
git commit -m "commit pertama" README.md
git push

Verifikasi melalui console, dan pastikan file README.md nya sudah ada.

Selain membuat repo dari awal, kita bisa migrasikan repo dari GitHub dan Bitbucket ke Cloud Source Repositories. Masuk ke dashboard dan klik Add repository.

Pilih Connect external repository. Lalu klik Continue.

Pilih project, dan Git provider misal GitHub. Ceklis lalu klik Connect to GitHub.

Kita akan diarahkan ke tampilan dimana kita harus mengautorisasi akses GCP ke akun GitHub milik kita.

Dan setelah di allow, akan diarahkan kembali ke tampilan form sebelumnya. Pilih repo yang akan digunakan, misal saya alertbot-tele.

Scroll kebawah dan klik Connect selected repository.

Akan ada pop up yang menandakan bahwa repo sudah terhubung.

Dan hasilnya seperti berikut ini. Isinya akan sama persis seperti yang berada di GitHub.

Selamat mencoba dan sekian!

Upgrade PC Tanpa Menggoncang Tabungan

Suatu ketika saya ingin meng-upgrade PC saya tapi kok rasanya berat hati untuk menyentuh tabungan. Rasanya kok keinginan tersebut tidak pada prioritas yang betul kalau sampai tabungan terkorek. Apa lagi sebentar lagi saya akan punya anak, tentu tidak betul kalau sampai pundi-pundi yang sudah diatur sedemikian rupa jadi terganggu. Terus bagaimana dong?

Decluttering

Ada orang-orang yang dengan mudah menyingkirkan barang yang tidak mereka perlukan, ada pula orang yang perlu arahan/motivasi lebih untuk melakukan itu. Saya adalah jenis orang yang kedua.

Ada dua buah buku yang saya baca secara berurutan pada tahun 2018, yaitu The Life-Changing Magic of Tidying Up oleh Marie Kondo dan Goodbye, Things oleh Fumio Sasaki.

Ide soal spark of joy dari Marie Kondo tidak begitu masuk ke kepala saya. Banyak benda yang tidak memenuhi kriteria tersebut tapi kalau disingkirkan dari hidup saya maka saya akan menjadi kesusahan secara tidak perlu. Nasihat-nasihat dari Fumio Sasaki lebih mengena di hati dan kepala.

Saat menulis buku tersebut, Fumio Sasaki adalah pria lajang tanpa tanggung jawab yang banyak, bahkan tanpa pacar. Jadi nasihat-nasihatnya sangat ekstrim. Saya juga sudah pernah beberapa kali melakukan decluttering, baik dengan giveaway mau pun dengan penjualan namun saya belum pernah mencobanya dengan cara yang ekstrim. Sekarang saya dapat melakukannya.

Keputusan memiliki anak ada trade-off-nya: ada banyak hal yang tidak dapat saya lakukan lagi dikarenakan waktu dan tenaga yang terbagi untuk keluarga. Setelah saya pikir-pikir, ternyata saya:

  • Tidak bisa naik gunung sampai 5-10 tahun ke depan.
  • Mengganti olahraga saya dengan yang lebih sederhana seperti jogging. Ditambah kondisi pandemi, saya tidak lagi bersepeda jauh-jauh untuk berolahraga.
  • Sulit/tidak dapat meluangkan waktu untuk beberapa mainin/koleksi.

Artinya benda-benda yang terkait dengan kegiatan di atas tidak lagi berguna untuk saya. Jadi saya memutuskan untuk menjual barang-barang saya tersebut: alat-alat dan perlengkapan mendaki gunung, sepeda, mechanical keyboard, beberapa barang elektronik, barang-barang yang duplikat (misal saya punya tetikus 2 buah), barang-barang yang dibeli sebagai cadangan, barang-barang pemberian, dan sebagainya. Pokoknya banyak banget! Banyak dari benda-benda itu adalah barang kesayangan, koleksi, dan memiliki kenangan namun manfaatnya untuk saya tidak ada. Manfaatnya untuk keluarga saya lebih nihil lagi. Apa yang lebih nihil dari nihil?

Saya tidak dapat menjelaskannya sebaik Fumio Sasaki. Jika kamu termasuk orang yang perlu motivasi tambahan untuk menyingkirkan barang-barang tidak terpakai, Goodbye Things boleh dicoba.

Strategi penjualan

Saya menjual semuanya dengan harga jual 3/4 harga beli. Bahkan ada yang setengah harga beli jika saya pikir barang tersebut sulit ditemukan pembelinya. Jika yang membelinya adalah orang yang saya kenal baik, maka saya memberinya kepercayaan untuk cicilan yang bebas diaturnya sendiri. Ada yang mengambil cicilan 1 tahun, ada pula yang mengambil cicilan 1.5 tahun. Dengan adanya cicilan ini, saya mesti menyediakan semacam dana buffer yang nantinya harus diganti oleh piutang cicilan ini. Dana ini dapat saya gunakan dengan segera untuk upgrade.

Kurang dalam 2 minggu penjualan, ditambah hasil penjualan spare part PC yang mau diupgrade, saya berhasil mengumpulkan dana sekitar 18 juta rupiah. Saya juga kaget dengan kalkulasi ini. Tapi saya hanya menggunakan sekitar 7-8 juta rupiah untuk upgrade PC. Selebihnya bisa masuk tabungan. Asyik kan?

Spesifikasi unit PC sekarang

Jika ditambahkan dengan nilai dari sebelum di-upgrade, totalnya Rp 16.301.000. Lumayan juga, tapi saya cukup senang dengan hasil ini.

Dari rig lama, pembelian 2020:

  • AMD Ryzen 5 3400G, Rp. 2.080.000
  • Zotac NVidia 1660 Ti AMP, Rp. 4.000.000
  • Nvme M2 SSD Intel 660P 512GB, Rp 1.507.000

Upgrade 2021:

  • Gigabyte B450 I Aorus Pro Wifi, Rp 2.158.000
  • RAM G.SKILL F4-3200C16D-16GFX FlareX 16GB (2x8GB) DDR4 3200Mhz, Rp. 1.363.000
  • Corsair - SF750 80 Plus Platinum 750 Watt SFX P, Rp. 2.668.000
  • CPU cooler Noctua NH-L9a AM4, Rp. 698.000
  • Geeek A50 Plus White ITX Case, Rp. 1.510.000
  • ID-COOLING NO-9215 92mm Slim Cooling Fan PWM, Rp. 231.000
  • Mini ITX Wifi & Bluetooth Antenna RP-SMA Female, Rp. 65.000
  • Audio Splitter Combiner, Rp. 21.000

Penampakan

Google Cloud: Cloud Firestore in Datastore Mode

Hai!

Pada jurnal ini, saya ingin membahas mengenai salah satu layanan di Google Cloud Platform, yaitu Cloud Firestore atau yang sebelumnya dikenal dengan Cloud Datastore Dan tentu saja dengan sedikit hands-on lab yang bisa teman-teman coba sendiri.

Cloud Firestore merupakan layanan NoSQL database di GCP yang sangat fully-managed dan memiliki skalabilitas yang tinggi. Penggunaan Cloud Firestore biasanya untuk mobile app database (mirip tapi tidak sama dengan firebase), server/client library database, dsb. Lebih lengkap contohnya disini ya https://cloud.google.com/firestore/docs/samples.

Banyak kelebihan dari Firestore yang bisa dimanfaatkan, antara lain serverless database yang mudah untuk scaling, kompatibilitas dengan mobile, web, dan IoT app yang tinggi, sinkronisasi bisa dilakukan offline / online, mudah kustomisasi, dan sangat mudah untuk diintegrasikan dengan layanan GCP lainnya seperti Firebase, Cloud Functions, dll. Lebih lengkap bisa dibaca disini ya https://cloud.google.com/firestore

Di jurnal ini kita akan praktik mengenai bagaimana membuat database Firestore NoSQL dalam mode Cloud Datastore. Database nya sangat sederhana yaitu berisi mata pelajaran:)

Pertama, pastikan Cloud Datastore API nya aktif. Ini berfungsi sebagai API untuk Cloud Firestore sebagai NoSQL database di GCP. Masuk ke Navigation Menu > APIs & Services > Library. Search Cloud Datastore API dan klik enable.

Jika sudah, kita beralih ke Firestore. Masuk ke Datastore > Entities

Pada saat kita pertama kali menggunakan Cloud Firestore, kita harus memilih mode. Disini saya pilih Datastore Mode. Untuk perbedaanya bisa dilihat juga di tangkapan layar di bawah ini. Klik Select DataStore Mode.

Lalu pilih lokasi. Pilih lokasi terdekat dengan user. Misal disini saya pilih asia-northeast1 (Tokyo). Lalu klik Create Database.

Tunggu beberapa saat dan hasilnya akan seperti di bawah ini. Database siap untuk digunakan. Untuk membuat entitas, klik Create Entity.

Oh iya, entity ini bisa diibaratkan sebuah database ya.

Misal disini Kind: Jadwal Kuliah. Lalu klik Create

Hasilnya akan seperti di bawah ini. Sebuah entitas akan memiliki ID. Kita coba klik ID nya untuk melihat detail.

Dan hasilnya seperti berikut. Sebuah entitas akan memiliki namespace, kind, key, key storal, dan url-safe key. Kita coba isi datanya. Klik Add Property.

Property pertama:

  • Name: Kelas
  • Type String
  • Value: TRPL A

Klik Done.

Klik Add Property lagi, isikan:

  • Name: Jumlah Siswa
  • Type: Integer
  • Value: 22

Klik Done.

Klik New Property lagi, isikan:

  • Name: Mata Kuliah
  • Type: String
  • Value: Pemrograman Dasar

Klik Done.

Klik New Property lagi, dan isikan:

  • Name: Waktu
  • Type: Date and Time
  • Value: 4/6/21 10:00 AM

Sesuaikan time zone dan klik Done.

Kita klik New Property lagi, isikan:

  • Name: Tepat Waktu
  • Type: Boolean
  • Value: True

Klik Done.

Okay. Untuk jurnal ini, 1 entitas cukup berisi 5 properti. Bisa disesuikan masing-masing ya! Hasilnya akan seperti berikut ini. Klik Save.

Buat dua entitas lagi dengan Kind yang sama yaitu Jadwal Kuliah. Misal seperti di bawah ini.

Nah untuk memanggil query dari entitas, masuk ke tab Query by GQL. Dan tulis:

SELECT * from `Jadwal Kuliah`;

Lalu klik Run Query.

Bisa jalankan query nya dengan spesifik value, misal:

SELECT * FROM Jadwal Kuliaj WHERE `Jumlah Siswa` = 22

Lalu klik Run Query.

Selamat mencoba dan sekian!

Google Cloud: Working with Google Cloud SQL Instances

Hai!

Pada jurnal ini saya ingin sharing mengenai Google Cloud SQL yang mana merupakan salah satu services untuk database management di Google Cloud Platform. Layanan Cloud SQL ini berfungsi untuk manaje relational database seperti MySQL, PostgreSQL, dan SQL Server.

Sebenarnya, secara sederhana saat kita membuat SQL instance, itu bisa diibaratkan kita membuat sebuah vm dan didalamnya diinstal paket database seperti mysql. Nah, karena banyaknya kesulitan untuk manajemen database saat ditempatkan di vm seperti susahnya untuk migrasi, HA (harus setup galera), dan upgrade versi paket maka Cloud SQL ini bisa menjadi solusi.

Banyak fitur yang ditawarkan oleh Cloud SQL, seperti auto-provision, fully-managed, dan lain-lain. Bisa dibaca secara lengkap di https://cloud.google.com/sql/docs.

Disini akan saya jelaskan sedikit praktiknya. Untuk lebih advanced, bisa jadi akan dibahas di jurnal selanjutnya:)

Langsung saja ya!

Jika ingin masuk ke console untuk manaje Cloud SQL, dari dashboard > SQL.

Saat kita sudah membuat sebuah SQL instance, maka akan tampil daftarnya di dashboard SQL. Jika belum ada, akan kosong seperti di bawah ini. Untuk membuat SQL instance baru klik Create Instance.

Di Google Cloud SQL, saat jurnal ini ditulis menawarkan tiga tipe database engine yaitu MySQL, PostgresSQL, dan SQL Server. Khusus untuk jurnal ini, saya pilih MySQL.

Selanjutnya akan muncul tampilan untuk mengisi informasi tentang SQL instance yang ingin dibuat. Definisikan ID, password untuk user root, pilih versi database, dan region. Kelebihan di Cloud SQL yaitu kita bisa set multiple zone yang artinya instance akan ditempatkan di beberapa zone yang berbeda. 🙂

Pilih zone dan scroll kebawah lalu klik Show Configuration Options.

Kita bisa atur pengaturan yang lebih advanced, seperti tipe mesin. Disini saya pilih standard dengan 1 vCPU dan 3.75 GB ram. Untuk pengaturan lain bisa disesuaikan ya! Lalu klik Create Instance.

Tunggu beberapa saat hingga centang hijau muncul yang menandakan SQL instance berhasil dibuat seperti berikut ini.

Bisa klik instance ID untuk melihat detailnya. Pada sisi atas kita bisa manaje instance seperti edit, import database, export database, restart instance, stop, delete, dan clone.

Pada sisi kiri lebih ke manajemen internal seperti mengatur koneksi untuk database, user apa yang boleh mengakses, database apa saja yang ada di instance, backup, replika, dan operations.

Kita coba klik tab Database. Secara default, ada 4 database yang terbuat. Ini sama persis saat kita menginstall paket mysql di vm, otomatis akan ada 4 database. Untuk membuat database baru, klik Create Database.

Definisikan nama, dan biarkan default untuk yang lain. Lalu klik Create.

Hasilnya akan seperti di bawah ini.

Lalu, coba masuk ke tab Users. Disana, secara default ada 1 user yaitu root, dengan password yang sudah didefinisikan di awal saat pembuatan instance. Hostname dengan tanda % maksudnya semua akses darimana saja bisa menggunakan user root.

Kita coba buat user baru, klik Add User Account.

Definisikan username, password dan bisa definisikan pula Hostname. Misal kita spesifikan bahwa user ananda hanya dapat diakses menggunakan IP Address tertentu. Tapi kali ini, saya gunakan Any. Lalu klik Add.

Hasilnya akan seperti berikut ini.

Setelah kita definisikan username dan database, apakah bisa langsung diakses dari laptop kita? belum:)

Karena di Cloud SQL kita harus definisikan Connections yang berfungsi untuk membatasi akses. Ini sangat bermanfaat karena bisa diibaratkan layer security nya Cloud SQL. Jadi, tidak sembarang orang bisa mengakses database dan bahkan Cloud SQL instance kita.

Masuk ke tab Connections. Centang Public IP karena saya ingin coba mengaksesnya dari laptop, dan klik Add Network.

Definisikan nama network, dan CIDR networknya ya. Misal saja disini saya 0.0.0.0/0 🙂 (untuk latihan, karena dalam skala production, bisa dipersemit untuk network tertentu saja). Klik Done dan klik Save.

Bisa kita coba akses melalui laptop, maka akan bisa diakses seperti di bawah ini.

Saat kita manaje database melalui laptop, maka data akan otomatis ter-sinkron dengan data yang ada di console. Misal saya buat database baru bernama mydb. Maka hasilnya akan seperti di bawah ini.

Oh iya, selain cara di atas yang sudah pasti sangat familiar untuk terhubung ke database melalui IP Address, kita bisa menggunakan cara lain juga. Masuk ke tab Overview dan disana akan ada beberapa cara yang bisa menjadi opsi. Bisa menggunakan Connection name misal jika database langsung terkoneksi ke layanan GCP lainnya, atau bisa melalui Cloud Shell.

Disini saya coba klik Connec using Cloud Shell.

Sebelum klik, pastikan API Cloud SQL Admin API sudah diaktifkan ya:)

Dan saat diklik akan otomatis dialihkan ke Cloud Shell seperti berikut ini.

Sangat mudah, bukan? Selamat mencoba dan sekian!

Google Cloud: Managing Snapshots on Google Compute Engine

Hai!

Pada jurnal ini saya akan membahas tentang fitur snapshot di Google Compute Engine. Snapshot berfungsi untuk mem-backup data terbaru dan terkini. Mengapa disebut terbaru, karena ia memiliki kelebihan dimana snapshot bisa dibuat walau instance masih berjalan alias tidak perlu dimatikan dulu.

Selain snapshot digunakan untuk pembuatan instance baru, snapshot bisa digunakan untuk membuat custom image. Penjelasan lengkap bisa dibaca disini ya https://cloud.google.com/compute/docs/disks/create-snapshots dan https://cloud.google.com/sdk/gcloud/reference/compute/disks/snapshot.

Disini kita akan coba membuat sebuah skenario untuk snapshot. Pertama, saya sudah terlebih dahulu membuat instance dengan firewall Allow-HTTP nya dicentang dan dalam instance sudah diinstall pake nginx.

Saya coba ubah file index.html menjadi seperti berikut ini:

Lalu coba masuk ke menu Snapshots. Disini saya belum memiliki snapshot satupun, jadi masih kosong. Untuk membuat snapshot, klik Create Snapshot.

Definisikan nama snapshot, misal backup-instance-1 dan pastikan source-disk nya mengarah ke disk instance-1 ya. Untuk lokasi bisa pilih multi-regional atau regional. Jika sudah, klik Create.

Jika berhasil, hasilnya akan seperti berikut ini. Terlihat snapshot nya ada dengan ukuran yang kecil karena ini menyesuaikan isi data dari instance.

Lalu, di instance-1 saya coba ubah lagi file index.html menjadi seperti berikut ini.

Untuk snapshot kedua, saya coba buat lewat cli.

gcloud compute disks snapshot instance-1 --snapshot-name=backup-instance-1-v2 --zone=asia-southeast2-a --storage-location=asia

Lalu verifikasi snapshot nya.

gcloud compute snapshots list

Dan bisa dilihat detail dari snapshot menggunakan perintah:

gcloud compute snapshots describe backup-instance-1-v2

Selanjutnya kita akan lakukan pengujian dengan membuat instance baru dimana disk nya adalah snapshot yang dibuat tadi.

Pengujian pertama melalui console untuk snapshot pertama yang dibuat di awal. Masuk ke menu VM Instances, klik Create Instance.

Hal yang perlu diperhatikan adalah pastikan region dan zone nya sama dengan tempat dimana snapshot berada.

Centang allow http traffic dan pada boot disk klik Change.

Masuk ke tab Snapshot, dan pilih snapshot yang dibuat pertama. Lalu klik select.

Lalu klik create instance dan hasilnya seperti berikut ini:

Saat diakses, maka akan muncul tampilan sesuai sesaat sebelum snapshot pertama dibuat.

Pengujian kedua melalui cli menggunakan snapshot kedua. Disini alurnya sedikit berbeda, dimana snapshot harus dibuat disk terlebih dahulu:

gcloud compute disks create restore-instance-1-v2 --size=10 --zone=asia-southeast2-a --source-snapshot=backup-instance-1-v2

Lalu verifikasi disk:

gcloud compute disks list

Dan buat instance menggunakan disk yang dibuat dari snapshot sebelumnya:

gcloud compute instances create restore-instance-1-v2 --zone=asia-southeast2-a --subnet=asia-southeast-2 --service-account=sa-frontend@steady-syntax-305116.iam.gserviceaccount.com --tags=http-server --disk=name=restore-instance-1-v2,device-name=restore-instance-1-v2,mode=rw,boot=yes,auto-delete=yes

Verifikasi:

gcloud compute instances list

Saat diakses, maka akan muncul tampilan sesuai sesaat sebelum snapshot kedua dibuat seperti berikut ini.

Selamat mencoba dan sekian!

Google Cloud: Managing Disks on Google Compute Engine

Hai!

Pada jurnal ini saya ingin membahas disks atau penyimpanan di Google Compute Engine. Disk ini berbeda dengan storage yang ada di GCS ya, karena disk pada GCE bersifat block storage dimana biasanya ia digunakan untuk disk sistem operasi atau disk tambahan yang di attach, menjadi vdb misal. Dan khusus di GCP, banyak tipenya. Mereka memiliki kelebihan dan kekurangan masing-masing tentu saja. Selengkapnya bisa baca di dokumentasi ini > https://cloud.google.com/compute/docs/disks ya.

Disini kita akan coba praktik.

Untuk masuk ke menu Disks, bisa Compute Engine > Disks.

Tampilannya seperti di bawah ini. Jika kita memiliki instances yang didalamnya tentu saja ada disknya, maka akan muncul daftarnya dalam dashboard di bawah ini.

Untuk membuat disk baru, klik Create disk.

Isikan nama, sesuaikan region dan ukuran disk ya. Selain itu di jurnal ini saya biarkan default. Lalu klik Create.

Setelah, dibuat maka hasilnya akan seperti di bawah ini.

Dari sebuah disk, kita bisa melakukan beberapa action yang terkait dengan fitur-fitur lain di GCE. Kita bisa buat instance, snapshot, image, dan bahkan kita bisa clone atau menggandakan disknya.

Tapi di jurnal ini kita belum akan membahasnya lebih lanjut. Kita fokus pada disk nya terlebih dahulu. Untuk melihat detail dari disk, bisa klik nama disk, dan detailnya akan terlihat seperti di bawah ini. Kita pun bisa monitoring disk nya ya.

Kita coba untuk mengubah ukuran disknya, klik Edit. Lalu set ukuran disk nya. INGAT! bahwa ukuran hanya bisa ditambah, tapi tidak bisa dikurangi. Jadi misal ukuran sebelumnya 100GB, kita coba set menjadi 150GB. Lalu klik Save.

Hasilnya akan seperti berikut ini.

Selanjutnya, kita coba buat instance dimana disk yang dibuat tadi akan di attach sebagai secondary disk (disk kedua) sebagai tempat yang khusus untuk menyimpan data. Masuk ke menu VM Instances > Create Instance.

Hal yang wajib dikonfigurasi dengan benar adalah pastikan region dan zone sesuai dengan tempat dimana disk yang dibuat tadi berada. Untuk komponen lain, bisa disesuaikan.

Untuk attach disk, klik Management security, disks, networking, sole tenancy.

Masuk ke tab Disk dan klik Attach existing disk.

Pilih disk yang dibuat tadi, dan klik done. Lalu klik create untuk membuat instance nya.

Berikut hasil instance yang terbuat dan bisa klik nama instance untuk melihat detailnya.

Bisa dilihat bahwa terdapat dua disk yang ter-attach yaitu disk booting berisi debian-10 dan disk kosong yang dibuat tadi.

Kita coba mounting agar disk bisa digunakan untuk menyimpan data. Pertama, ssh instance dan verifikasi disk menggunakan perintah:

lsblk

Terlihat disk yang kedua bernama sdb.

Kita buat partisi menggunakan perintah fdisk dan format sesuai file system, misal disini menggunakan file sistem ext4. Langkah-langkahnya seperti tangkapan layar di bawah ini.

Dan lakukan mounting, misal ke folder /mnt/mydata.

lsblk
mkdir /mnt/mydata
mount /dev/sdb1 /mnt/mydata
lsblk
df -hT

Jadi, saat kita menyimpan data di /mnt/mydata maka data tersebut sudah tersimpan di disk vdb atau disk yang dibuat sebelumnya.

Selain menggunakan console, kita bisa membuat disk menggunakan cli di cloud-shell. Misal saya membuat disk bernama disk02 dengan ukuran 100GB, maka perintahnya:

gcloud compute disks create disk02 --size=100GB --zone=asia-southeast2-a

Dan untuk verifikasi:

gcloud compute disks list

Untuk melakkan resize, misal resize ke 150GB, perintahnya adalah:

gcloud compute disks resize disk02 --size=150 --zone=asia-southeast2-a
gcloud compute disks list

Untuk pengujian, bisa kita buat instance baru via cli juga:

gcloud compute instances create instance02 --zone=asia-southeast2-a --image=debian-10-buster-v20210316 --image-project=debian-cloud --service-account=sa-frontend@steady-syntax-305116.iam.gserviceaccount.com --network=custom-vpc01 --subnet=asia-southeast-2
gcloud compute instances list

Lalu kita attach disk nya ke instance yang baru saya dibuat:

gcloud compute instances attach-disk instance02 --disk=disk02 --zone=asia-southeast2-a

Kita verifikasi dengan melihat detail instance nya:

gcloud compute instances describe instance02 --zone=asia-southeast2-a

Terlihat bahwa disk yang ter-attach berjumlah 2 dan kita bisa lakukan verifikasi dengan langkah yang sama seperti sebelumnya menggunakan SSH.

Selamat mencoba dan sekian!

Google Cloud: Cloud Storage Lifecycle Rules

Hai!

Pada jurnal ini saya ingin membahas mengenai fitur lifecycle rules pada Google Cloud Storage. Secara sederhana, fitur lifecycle rules atau aturan siklus pada objek di GCS memungkinkan kita mengatur seberapa lama objek-objek tersebut berada di bucket. Katakanlah umur dari objek. Misal kita set 90 hari objek akan di delete, maka setelah 90 hari objek akan benar-benar dihapus secara otomatis.

Hal ini memiliki banyak keuntungan, terutama di dalam hal biaya. Semisal ada file backup yang sudah terlalu tua dan sebenarnya tidak kita butuhkan, tapi malah memakan cost. Jadi, sangat penting untuk diimplementasikan fitur lifecycle ini ya.

Di jurnal ini saya memiliki skenario. Pertama, kita buat bucket dengan storageclass multi-regional, buat dua rules via console (180 hari set ke nearline dan 365 hari set ke coldline), dan rule ketika via cloud-shell dengan file json untuk delete object setelah 730 hari.

Jadi siklus objek dalam bucket ini secara sederhana: jika objek sudah disimpan lebih dari 90 hari, maka otomatis tipe nya akan dipindah ke nearline, lalu saat umur file sudah 365 hari atau 1 tahun akan otomatis dipindah ke coldline, dan setelah 730 hari akan dihapus.

Untuk penjelasan lebih lengkap tentang tipe bisa dibaca di dokumentasi resminya di https://cloud.google.com/storage/docs/storage-classes dan di jurnal saya yang lain > Google Cloud: Setting Up Buckets in Google Cloud Storage (GCS).

Oh iya, untuk pembuatan bucket juga bisa di baca di jurnal saya yang di atas juga ya. Hasilnya akan seperti di bawah ini.

Masuk ke tab LifeCycle. Saat baru saja membuat bucket, rule nya masih kosong. Untuk menambahkan klik Add a Rule.

Rule pertama, kita buat object set to nearline setelah 180 hari. Pada opsi pemilihan action, pilih Set storage class to Nearline. Lalu klik Continue.

Ceklis age (isikan 180) dan storage class matches (pilih standard dan multi-regional). Storage class matches ini maksudnya adalah objek-objek yang memiliki storage class yang di ceklis maka akan terkena rule ini. Lalu klik create.

Jika berhasil dibuat, hasilnya akan seperti di bawah ini.

Untuk rule kedua, kita klik add a rule lagi lalu pada pemilihan action pilih set storage class to coldline. Klik continue.

Ceklis age (isikan 365) dan storage class matches pilih nearline karena rule ini mengikuti rule pertama yang dibuat sebelumnya. Lalu klik create.

Hasilnya akan seperti di bawah ini. Akan terlihat dua rules yang sudah dibuat.

Selain via console, kita bisa verifikasi lifecycle via cloud-shell dengan perintah:

gsutil lifecycle get gs://<BUCKET_NAME>

Oke, selanjutnya kita coba buat rule ketiga menggunakan cli. File untuk set lifecycle ini berbentuk json. Saat mencoba, bisa menggunakan repo dari saya, atau kustom sendiri ya!

git clone https://github.com/misskecupbung/gcs-101
cd gcs-101/
ls

Kita apply lifecycle nya dan verifikasi lagi:

gsutil lifecycle set delete-after-two-years.json gs://<BUCKET_NAME>
gsutil lifecycle get gs://<BUCKET_NAME>

Hasilnya pun bisa dilihat dari console ya:

Selamat mencoba dan sekian!

Google Cloud: Managing Versions and Split Traffic of an App Engine Application

Hai!

Pada jurnal ini, saya ingin sharing mengenai salah satu services PaaS di GCP, yaitu App Engine. Pada jurnal ini ada skenario dimana pertama deploy aplikasi dan set ke versi 1, ubah file pada aplikasi, lalu deploy aplikasi lagi dengan mengaturnya menjadi versi 2, dan melakukan split traffic.

Langsung saja ya!

Disini saya menggunakan aplikasi dari link > https://github.com/GoogleCloudPlatformTraining/cp100-bookshelf. Clone repo tersebut di cloud shell.

git clone https://github.com/GoogleCloudPlatformTraining/cp100-bookshelf

Setelah masuk ke direktori aplikasi, instal requirement dari aplikasinya terlebih dahulu.

pip install -r requirements.txt -t lib

Lalu deploy aplikasi dan set versinya menjadi versi 1.

gcloud app deploy --version 1

Bisa set lokasi terdekat ya. Dan hasilnya akan seperti berikut jika sudah berhasil di deploy.

Jika url dibuka lewat browser, tampilannya seperti berikut ini:

Jika kita menambahkan buku melalui browser seperti berikut ini:

Lalu buka BookShelf app melalui console.

Dan verifikasi datastore tempat dimana database app engine berada, kita akan menemukan data buku yang sebelumnya ditambahkan.

Selanjutnya, kita akan coba buat versi 2 dari aplikasi BookShelf nya. Agar terlihat perbedaanya, bisa edit file base.html di cp100-bookshelf > app-engine > bookshelf > templates. Seperti misal di bawah ini.

Lalu deploy aplikasi dengan set parameter versi 2.

gcloud app deploy --no-promote --version 2

Pastikan berhasil ya:

Dan hasil aplikasi versi 2 nya adalah seperti berikut ini:

Perhatikan perbedaan dibagian title nya ya.

Selanjutnya, kita akan coba split traffic. Buka Dashboard > App Engine > Versions. Terlihat bahwa traffic di aplikasi versi 1 adalah 100%, dan versi 2 adalah 0%.

Untuk split traffic, klik tombol split traffic di sisi atas aplikasi. Set Random, klik add version 2, dan set allocationnya menjadi 10%. Lalu klik save.

Hasilnya akan seperti berikut ini:

Maka, saat kita buka url aplikasi versi pertama, akan bisa muncul aplikasi dari versi 2. Perbandingannya 1:9. Sesuai alokasi yang dibuat sebelumnya.

Biasanya, split traffic digunakan untuk memindahkan traffic sedikit demi sedikit aplikasi dari versi lama ke versi baru, agar tidak ada downtime. Bisa disesuaikan allocationnya ya. Selamat mencoba!

Sekian!

Buku Belajar Komputer Tingkat Dasar 5 Tema 1

Puji syukur tim penulis panjatkan kepada Tuhan Yang Maha Esa yang telah memberikan rahmat dan karunia-Nya, setelah molor beberapa waktu akhirnya buku Belajar Komputer Tingkat Dasar 5 Tema 1 yang kami tulis hari ini bisa rilis.


Buku ini adalah lanjutan dari buku Belajar Komputer Tingkat Dasar 4 yang sudah terbit sebelumnya. Seperti pada buku sebelumnya, materi dalam buku ini juga masih mengusung tema belajar dan bermain secara menyenangkan.
Adapun beberapa materi dalam buku ini adalah:
  • Materi pada bab 1 berisi pelajaran geografi yaitu mengenal negara-negara di berbagai dunia, sehingga anak-anak dapat mengetahui nama benua dan negara di dunia. Di dalam bab ini juga berisi permainan tentang wilayah dalam berbagai negara di dunia.
  • Bab 2 berisi pelajaran huruf braille, yaitu huruf yang biasa digunakan oleh orang-orang tidak bisa melihat. Dengan menggunakan huruf braille, orang yang tidak bisa melihat bisa membaca. Di dalam bab ini juga dijelaskan sejarah singkat terciptanya huruf braille.
  • Bab 3 berisi pelajaran cara bermain catur untuk anak-anak. Di dalam bab ini dijelaskan pengetahuan dasar mengenai catur, notasi pada permainan catur, gerakan berbagai buah catur. Materi pelajar pada bab ini dapat dilakukan lewat permainan di komputer ataupun menggunakan perangkat catur asli yang tersedia.
 Untuk mengunduh buku digital Belajar Komputer Tingkat Dasar 5 Tema 1 silakan pilih salah satu tautan berikut:

Pembaca boleh menyebarkan buku versi digital ini ke masyarakat yang membutuhkan baik secara online ataupun offline, juga dipersilakan untuk membuat mirror di berbagai web atau server yang pembaca miliki.


-

Google Cloud: Custom-Mode VPCs on GCP

Hai!

Setelah membuat auto-mode VPCs di jurnal sebelumnya (baca: https://misskecupbung.wordpress.com/2021/03/14/google-cloud-how-to-creating-auto-mode-vpcs-easily/), disini kita akan coba membuat custom-mode VPCs ya.

Seperti namanya, custom-mode berarti kita bisa definisikan sendiri komponen-komponen VPCs nya sesuai kebutuhan. Komponen apa saja itu? mari kita coba menggunakan skenario.

Skenario dalam jurnal ini adalah pertama kita buat custom-mode VPCs, lalu buat service account baru dengan roles logs writer dan monitoring, buat instance template beserta instance group dimana kita gunakan service account yang baru saja dibuat (instance akan mendapatkan permission sesuai roles) dan terakhir adalah pembuatan firewall dimana metodenya berdasarkan service account dan network-tag. So, firewall hanya akan diapply sesuai service account dan network-tag saja.

Mari kita mulai.

Masuk ke menu VPC Networks > VPC Networks. Tampilannya akan seperti di bawah ini dimana ada dua buah VPCs (default terbuat otomatis bersamaan saat project dibuat dan yang satunya dibuat di jurnal sebelumnya).

Disini kita akan hapus semua dan buat VPCs dengan mode custom. Untuk menghapus, klik nama VPCs.

Setelah masuk ke tampilan detail, klik Delete VPC Network.

Akan muncul pop up konfirmasi, klik DELETE.

Ulangi dengan langkah yang sama untuk menghapus VPCs kedua hingga semua sudah terhapus ya. Untuk membuat VPCs baru klik Create VPC Network.

Kita definisikan nama dan deskripsi bila perlu, dan yang jadi perbedaan dengan auto-mode yaitu pada Subnet Creation Mode, pilih Custom.

Lalu kita definisikan nama subnet, region tempat dimana subnet berada, beserta range ip nya ya. Sebagai opsional bisa set Private Google Access dan Flow logs, setelah itu klik Done.

Untuk membuat subnet baru lagi (misal untuk region yang berbeda) bisa klik Add Subnet. Disini saya masih buat 1 aja ya. Lalu set Dynamic routing mode menjadi Regional. Perbedaan dari keduanya yaitu jika Regional untuk satu region saja, dan untuk Global bersifat global dan biasanya digunakan untuk VPN. Lalu klik Create.

Hasilnya akan seperti berikut ini:

Selanjutnya, kita akan buat service account baru dan service account kita coba hapus saja, apakah bisa? bisa dong. Sebelum membuat service account, kita perlu buat roles nya. Ini merupakan custom roles dimana permissionnya bisa kita definisikan sendiri. Masuk ke IAM & Admin > Roles.

Tampilannya seperti berikut ini:

Roles baru yang akan dibuat memiliki akses untuk Logs Writer dan Monitoring Metric Writer. Agar tidak perlu cari satu-persatu, gunakan fitur filter. Centang kedua roles dan klik Create Role.

Definisikan nama, deskripsi bila perlu, dan ID.

Bisa dilihat di bawah ini, bahwa permission dari kedua role yang dipilih berjumlah 7 sesuai permission dari kedua roles bawaan yang dipilih sebelumnya, lalu klik Create.

Hasilnya seperti berikut ini:

Untuk assign roles ke service account sebenarnya tinggal pilih roles > edit dan assign. Tapi dengan menggunakan cara tersebut, service account yang digunakan adalah default. Padahal kita ingin membuat service account baru bukan? kita tidak menggunakan carai klik edit.

Untuk membuat service account, masuk ke menu Service Accounts. Kita hapus dulu defaultnya denan pilih service account > Delete.

Pada pop up konfirmasi, tulis service account nya, dan klik Delete.

Sudah kosong dan klik Create Service Account:

Definisikan nama dan id dari service account, lalu klik create.

Nah, pada saat grant option, kita pilih roles yang sudah dibuat tadi. Jadi artinya service account yang sudah kita buat memiliki permission logs writer dan monitoring sesuai yang sudah didefinisikan sebelumnya. Lalu klik continue.

Biarkan default, dan klik Done.

Hasilnya akan seperti berikut ini:

Selanjutnya, kita buat instance template. Klik Compute Engine > Instance Templates

Klik Create Instance Template dan pada form, bisa definisikan nama, dan spesifikasi mesinnya ya. Ini sesuai kebutuhan. Lalu gulir ke bawah.

Nah, pada opsi Identity and API access, pilih service account yang sudah dibuat sebelumnya. Oh iya, karena ini service account buatan sendiri, maka tidak ada opsi access scope, access scope hanya diperuntukkan untuk service account default. GCP akan menganggap permission nya sudah sesuai dengan apa yang didefinisikan di roles services account (pada contoh ini logs writer dan monitoring ya). Lalu klik Management, security, disks, networking, sole tenancy.

Buka tab networking, dan sesuaikan dengan VPCs yang sudah dibuat sebelumnya. Lalu klik Create.

Hasilnya akan seperti berikut ini:

Lalu kita buat instance group dari instance template yang sudah dibuat. Buka menu Instance Group > Create instance group

Definisikan nama, lokasi multi-region, sesuaikan region dengan region tempat VPCs berada, dan pilih instance-template yang sudah dibuat. Lalu gulir ke bawah.

Biarkan yang lain default, atau bisa disesuaikan masing-masing. Disini saya coba minimum instance 2 dan maximum nya 3. Jika sudah klik Create.

Hasilnya akan seperti berikut ini. Pastikan tercentang hijau ya. Artinya instance group dalam keadaan baik. Lalu klik nama instance group untuk melihat detailnya.

Seperti di bawah ini, terlihat jumlah instance yang berada di instance group ada 2. Sesuai dengan yang didefinisikan di template.

Mari kita coba ping salah satu. Apakah bisa? hasilnya tidak bisa. Mengapa?

Jika kita cek, di dalam detail VPCs Networks, pada tab Firewall Rules masih kosong, yang artinya semua trafik tidak boleh masuk, keluar, ataupun lewat (ingress allow dan egress deny. hanya terdapat di VPCs default ya). Untuk membuat firewall baru, klik Add Firewall Rule.

Definisikan nama dan deskripsi bila perlu. Pada rule pertama ini, saya ingin coba mengijinkan trafik masuk khusus paket icmp agar bisa servernya bisa diping. Jadi direction pilih ingress, dan action pilih allow.

Saat penulisan jurnal ini, target untuk firewall di GCP ada tiga. Dimana untuk semua network, spesifik netwok-tag, dan service account. Jadi, rule hanya akan diapply berdasarkan targetnya saja.

Disini saya pilih target nya spesific service account, dan pilih service account yang sudah dibuat tadi. Jadi, rule hanya akan diapply ke instance yang menggunakan service account tersebut. Untuk source pilih 0.0.0.0/0. Pada bagian protocol, centang bagian other dan isikan icmp. Lalu klik create.

Hasilnya akan seperti berikut ini:

Dan instance sudah bisa diping.

Karena tadi kita hanya definisiin icmp saja, saat kita ssh salah satu instance, hasilnya tidak akan bisa. Seperti berikut ini.

Mari kita buat firewall untuk SSH nya dengan metode berbeda, yaitu network-tag. Untuk nama, network, direction dan action masa sama. Lalu gulir ke bawah.

Dan target nya pilih Spesific target tags, dan definisiin tag nya ya. Misal allow-ssh-tag. Untuk source set ke 0.0.0.0/0 dan protokol set ke tcp 22. Lalu klik create.

Hasilnya akan seperti berikut ini:

Agar bisa diaplikasikan ke instance, kita harus update instance nya. Saya coba untuk salah satu instance, format perintahnya:

gcloud compute instances add-tags [instance-name] --tags=[tag] --zone [zone-instance]

Saat diverifikasi maka akan muncul tag nya di vm instance details:

Dan ya… insance bisa di ssh.

Sekian!

Google Cloud: How to Creating Auto-Mode VPCs Easily

Hai!

Pada jurnal ini saya ingin membahas tentang VPC atau Virtual Private Networks di GCP. Berdasarkan sumbernya di https://cloud.google.com/vpc/docs/vpc, VPC merupakan jaringan virtual yang diterapkan di GCP menggunakan Andromeda. VPC ini menggunakan teknologi SDN dan fungsi utamanya adalah sebagai penghubung konektivitas instance, cluster, app engine, dll.

VPC terdiri dari network dan subnet. Pengertiannya kurang lebih sama seperti network dan subnet pada umumnya. Dalam pembuatan sebuah VPC, ada dua mode yang ditawarkan oleh GCP, auto-mode dan custom. Perbedaanya adalah di auto-mode, subnet akan terbuat secara otomatis beserta firewallnya. Subnet yang dibuat secara otomatis akan menggunakan rentang IP 10.128.0.0/9 dan itu akan dibuat secara otomatis ditiap region, sedangkan custom akan tanpa subnet dan kita harus definisikan sendiri beserta lokasinya.

Untuk custom mode, akan saya bahas di jurnal selanjutnya. Untuk jurnal ini akan saya bahas terlebih dahulu auto-mode. Untuk masuk ke menu VPC -> Navigation Menu -> VPC Network -> VPC Networks.

Secara default, ketika kita membuat project baru, otomatis akan dibuatkan vpc bernama default yang berisi subnet di tiap region dan akan dibuatkan default firewall pula berjumlah 5. Apakah default VPC bisa dihapus? bisa banget.

Tapi disini saya hanya akan membuat vpc baru. Klik Create VPC Network.

Dalam form pembuatan VPC dengan mode auto, pastikan pilih Automatic saat memilih Subnet creation mode.

Berikut rentang ip yang akan dibuat ketika kita pilih auto-mode, dimana subnet akan dibuat ditiap region.

Dan seperti yang sudah dijelaskan di awal, ketika pilih automatic, akan dibuatkan firewallnya juga. Firewall default untuk allow icmp, rdp, ssh, deny all ingress (tolak semua trafik masuk), dan allow all egress (ijinkan semua trafik keluar). Yup, secara default di GCP adalah ijinkan semua trafik keluar, dan tolak semua trafik masuk.

Bisa pilih opsi Regional atau Global. Perbedaan keduanya adalah jika regional, router akan melakukan routing di lingkup regional saja. Jika global akan secara dinamis melakukan routing disemua region dengan VPN atau interconnect dan cloud router. Bisa set MTU (ini bisa diubah atau biarkan default, karena ini berkaitan dengan unit transmisi), lalu klik Create.

Setelah berhasil, tampilan sedikit banyak mirip dengan default bukan?

Sampai jumpa di jurnal selanjutnya. Sekian!

Google Cloud: InstanceTemplates and Instance Groups on GCP

Hai!

Pada jurnal ini saya ingin membahas mengenai instance group dan instance template yang merupakan salah dua dari sekian banyak fitur keren di GCP.

Pertama adalah instance template dimana fungsinya adalah sebagai template untuk pembuatan instance atau vm. Mungkin bisa dibayangkan, jika kita ingin membuat banyak instance dengan spesifikasi ram, disk, os, hingga firewall yang sama, akan sangat repot kalau membuatnya satu-per-satu.

Dan disinilah instance template berperan. Template ini berisi parameter apa saja yang akan di apply di instance yang kita buat. Dan template ini bersifat global. Ya, kita bisa gunakan template tersebut di semua region dan zona.

Di jurnal ini saya buat skenarionya mirip di jurnal sebelumnya. Bisa dibaca dulu di Google Cloud: How to Retrieve Instance Logs using the Google Stackdriver Logging Agent and Automatically Save them to a Bucket. Kita install stackdriver logging agent dan log nya akan tersimpan di bucket.

Bucket yang saya gunakan masih sama yaitu misskecupbung-bucket-01.

Untuk membuat instance template, bisa ke menu Compute Engine > Instance Templates.

Di bawah ini terlihat saya belum memiliki template satupun, dan untuk membuatnya klik Create Instance Templates.

Bisa dilihat di bawah ini. Bukankah sangat mirip dengan ketika kita membuat sebuah instance sungguhan? Perbedaan utama ketika kita membuat instance template dibanding instance sungguhan terletak di zona dan region. Di instance template tidak kita definisikan parameter tersebut.

Disini saya definisikan namanya my-instance-template, dengan tipe f1-micro,

Scroll kebawah dan pilih boot disk nya Debian, dan di Access scopes pilih Set access for each API.

Masih sama seperti jurnal sebelumnya, agar lognya dapat di import ke bucket secara otomatis, harus memliki akses Write Only di Storage. Lalu klik Management, security, disks, networking, sole tenancy.

Kita bisa tambahkan labels, startup script:

#! /bin/bash

# Echo commands as they are run, to make debugging easier.
set -x

# Stop apt-get calls from trying to bring up UI.
export DEBIAN_FRONTEND=noninteractive

# Make sure installed packages are up to date with all security patches.
apt-get -yq update
apt-get -yq upgrade

# Install Google's Stackdriver logging agent, as per
# https://cloud.google.com/logging/docs/agent/installation
curl -sSO https://dl.google.com/cloudagents/install-logging-agent.sh
bash install-logging-agent.sh

# Install and run the "stress" tool to max the CPU load for a while.
apt-get -yq install stress
stress -c 8 -t 120

# Report that we're done.

# Metadata should be set in the "lab-logs-bucket" attribute using the "gs://mybucketname/" format.
log_bucket_metadata_name=lab-logs-bucket
log_bucket_metadata_url="http://metadata.google.internal/computeMetadata/v1/instance/attributes/${log_bucket_metadata_name}"
worker_log_bucket=$(curl -H "Metadata-Flavor: Google" "${log_bucket_metadata_url}")

# We write a file named after this machine.
worker_log_file="machine-$(hostname)-finished.txt"
echo "Phew!  Work completed at $(date)" >"${worker_log_file}"

# And we copy that file to the bucket specified in the metadata.
echo "Copying the log file to the bucket..."
gsutil cp "${worker_log_file}" "${worker_log_bucket}"

Dan metadata yang mengarah ke bucket. Masih sama seperti jurnal sebelumnya:). Jika sudah klik Create.

Hasilnya akan seperti berikut ini. Jadi, dari template yang sudah kita buat kita bisa membuat instance langsung.

Oh iya. Ketika kita klik nama instance template, dan saat menunjukkan detailnya, kita tidak menemukan opsi untuk Edit karena memang tidak bisa diubah. Cara paling mudah adalah dengan Create Similar ya. Dan untuk membuat instance dari template yang sudah dibuat, klik Create VM.

Tinggal diverifikasi dan klik Create. Tidak perlu diubah-ubah (mungkin hanya nama instance untuk pembeda) karena memang tujuan dari template adalah mempermudah.

Hasil instance nya adalah seperti berikut:

Dan ketika kita tunggu beberapa saat setelah proses stress, file lognya akan muncul:

Ya, semudah itu.

Selain cara melalui menu instance template untuk membuat instance, kita bisa langsung dari menu VM instances. Klik Create Instance.

Dan pilih menu New VM instance from template, dan pilih template nya. Lalu klik Continue.

Prosesnya sama, bisa kita ubah nama instancenya untuk pembeda dan langsung create.

Otomatis instance nya akan terbuat dengan spesifikasi yang sama dengan instance sebelumnya.

Dan tentu saja, log bucket akan otomatis disimpan ke bucket. Karena kita sudah definisikan startup script di template sebelumnya ya.

Bisa dibaca lebih jauh di sumbernya ya: https://cloud.google.com/compute/docs/instance-templates/.

Setelah instance template, kita bahas Instance Groups. Fitur ini merupakan fitur dimana kita bisa mengelompokkan instance-intance yang sudah kita buat menjadi satu. Ada banyak alasan mengapa harus dikelompokkan, misal karena butuh ketersediaan aplikasi yang tinggi.

Instance group terdiri dari dua tipe, managed dan unmanaged. Berdasarkan laman resminya disini https://cloud.google.com/compute/docs/instance-groups/, tipe unmanaged, ia secara sederhana hanya mengelompokkan instance-instance di sebuah group menjadi satu. Fungsinya bisa untuk load balancing, dan instance-instance dalam satu grup tersebut tidak harus sama spesifikasinya. Sedangkan managed biasanya untuk menjalankan aplikasi yang sama di instance-instance dengan spesifikasi yang sama pula. Ini bisa disebut duplikasi atau salinan. Jadi, ketika salah satu instance down/crash disebuah instance group, aplikasi akan tetap berjalan.

Perbedaan yang paling terlihat adalah di tipe managed, sebuah group bisa melakukan autoscaling (instance akan dibuat secara otomatis ketika load sedang tinggi dan instance akan otomatis dihapus ketika load sedang rendah untuk menghemat biaya), autohealing (ketika salah satu instance crash, maka otomatis akan dibuat instance baru untuk menggantikannya), dan itu bisa multi zone dan bisa auto update.

Untuk membuat instance group bisa ke ke menu Instance groups > create instance group.

Pertama, kita coba buat unmanaged instance group, disini kita bisa definisikan region, zona, network, dan anggota dari groupnya. Tambahkan instance-instance yang dibuat menggunakan template sebelumnya. Klik Create.

Dan hasilnya akan seperti berikut. Ketika salah satu instance crash/down, otomatis yang menyala tidak akan bertambah dan beban kerja dari instance yang crash tadi akan dialihkan ke instance yang masih menyala.

Bisa klik nama instance group untuk melihat detailnya. Terlihat anggotanya ada dua.

Selanjutnya kita buat instance group dengan tipe managed. Klik Create instance group.

Perbedaannya akan terlihat sekali dibandingkan dengan tipe unmanaged, bahwa tipe managed parameternya lebih banyak. Kita definisikan nama, lokasi bisa set multiple zones, dan bisa kita pilih zona mana saja yang akan menjadi tempat instance berada.

Ini juga merupakan salah satu kelebihan dari managed, dimana ketika salah satu zona terkena bencana, aplikasi akan tetap menyala di zona lainnya. Lalu scroll kebawah.

Kita bisa definisikan autoscaling policy nya, dimana target CPU utilization ini merupakan batas maksimal toleransi sebuah CPU di instance. Misal disini saya set 30%, maka ketika utilisasi cpu di satu instance menyentuh angka 30%, maka akan otomatis membuat instance baru.

Lalu kita bisa set cool down period, minimum dan maksimum instance di instance group.

Dan Autohealing nya berupa health check. Ini fitur mirip ping yang akan memanggil sebuah host untuk memastikan apakah host tersebut menyala atau tidak secara berkala. Disini health check akan memanggil sebuah instance secara berkala dan ketika dipanggil tidak merespon, maka dianggap crash/down dan otomatis akan dimatikan dan dibuat baru atau di recreate.

Disini tidak saya bahas health check terlebih dahulu:) maka tidak saya set dan klik Create.

Haislnya akan seperti berikut ini. Bisa klik nama instance groupnya.

Dan ketika load tinggi, akan dibuat instance baru dan ketika load rendah, instance akan dihapus. Di bawah ini contoh proses ketika instance baru dibuat untuk menangani proses stress.

Sekian!

Using Git For Windows With MSYS2

Developing software in Windows using GCC, Make, etc., is a little bit challenging, we have several choices, but I choose MSYS2.

The problem is, with the default Git from it repository is not quite friendly with Windows, in order to make this a little bit friendly we can use Git for Windows, to install it we can follow the steps from their GitHub:


https://github.com/git-for-windows/git/wiki/Install-inside-MSYS2-proper


Migrasikan Konten Django Lama ke Jekyll

Para pengembang BlankOn Linux saat ini telah menggunakan Jekyll untuk beberapa situsnya, salah satunya adalah laman http://blankon.id. Penulisan konten berbasis Markdown dan situs statis merupakan pilihan yang diambil setelah beberapa tahun sebelumnya para pendahulu menggunakan Django untuk sebagian besar website mereka. Konsekuensinya konten-konten website lama yang berbasis Django tersebut perlu...

Permainan Baru di GCompris bagian 1 (Keyboard Bayi)

Awal bulan Oktober 2020 lalu penulis membaca pengumuman di Millis GCompris bahwa tim pengembang akan merilis GCompris V 1.0 pada tanggal 17 November 2020. Dengan adanya rencana rilis tersebut maka Server GCompris akan dibekukan pada tanggal 15 s/d 17 November 2020.

Dengan adanya pengumuman tersebut maka Tim Penerjemah GCompris Indonesia bergerak secara cepat melakukan diskusi melalui Telegram.

Nah di sini ternyata saya salah baca atau memahami tanggal dan bulan.


Yang seharus tanggal tanggal 15 November saya bacanya 15 September.

Pada rilis GCompris V 1,0 ini terdapat perubahan dan perbaikan pada beberapa permaianan, contohnya adalah permianan Jelajahi Peternakan Hewan, Permianan Catur, Menghitung Benda, Pengelompokan. dan lain-lain.

 

Selain itu terdapat juga beberapa permaian baru pada GCompris V1.0, yaitu: Keyboar Bayi, Listrik Analog, Labirin Pemrograman, Belajar Digit, Belajar Pengurangan,dan Belajar Penambahan.


Pada post kali ini penulis membahas permianan bernama Keyboard bayi, sedangkan permainan baru lainnya akan penulis bahas pada post berikutnya


Terjemahan pada judul permainan ini masih keliru, yang lebih tepat adalah Keyboard anak.
Tapi bisa dimaklumi karena tim penerjemah melakukan penerjemahan secara langsung dari judul aslinya yaitu Baby keyboard.



Permainan ini bertujuan sebagai sarana belajar memahami berbagai tombol pada keyboard sekaligus pengenalan huruf dan angka untuk anak-anak pada usia dini.

Cara memainkannya adalah Tekan tombol apa pun pada keyboard sesuai keinginan.
Maka Huruf, angka, atau karakter muncul di layar sesuai tombol yang ditekan tersebut.

Jika yang ditekan tombol berupa huruf dan angka maka keluar suara  sesuai tombol yang ditekan.
Jika yang ditekan tombol selain huruf dan angka maka suaranya hanya bleep.


Rencananya permainan ini akan penulis masukkan pada Buku Belajar Komputer Dasar tingkat 0 Tema 3 yang sedang penulis kerjakan, atau bisa jadi dimasukkan ke tema 1 atau 2 edisi revisi.

Untuk yang tertarik dengan buku yang penulis rilis dapat mengunjungi tautan berikut => Unduh Buku Digital Gratis



The First Verbeek Nightly Build with Package That Build by IRGSH

Today we’re pleased to announce our first nightly build (or “jahitan”) with package that build by our in-house toolchain IRGSH. This build featured Pop Shell extension package which marks our important milestone. The package help us to prove that IRGSH works as intended to help us to bring the source code to binary package, to injected it to signed repository then wrapped to a bootable ISO.

You can download the ISO file here. You may consider to use zsync to decerase the size of download between builds.

In case you’re curious about what Verbeek will be looks like, we’ve packaged Pop Shell because we want Verbeek to be developer-first desktop. The release will be providing software and tools you need as developer/IT professional. This is the third BlankOn Linux release that will have specific user as target, after Meuligoe Minimalist and Sajadah. If you want to get update about the development, please simply follow the BlankOn Linux Twitter account and click Watch on our release repository.

EJBCA Beginner Guide: From CA to Certificate Enrollment

X509 is a complicated thing and EJBCA makes it easier to grasp. Eww you may find EJBCA is complicated as well. This post will guide you to specific case as example:

CA that can issuing certificates for high education instutution. High education institution as end user can signing PDF files for their student certification.

This post is not the best practice example but it can introduce you to how EJBCA works. Let’s go.

EJBCA Preparation on local environment

docker-compose.yaml:

version: '3'

services:
  db:
    image: postgres:13-alpine
    env_file: .env
    restart: always
    volumes:
     - ./data:/data

  ejbca:
    image: primekey/ejbca-ce:6.15.2.6
    env_file: .env
    restart: always
    ports:
      - 80:8080
      - 443:8443
    depends_on:
      - db

.env:

# EJBCA
TLS_SETUP_ENABLED=simple
DATABASE_USER=postgres
DATABASE_PASSWORD=kLTPk5Ty9K3JHykCS38YBHDTVwXkVCgjsQs7HaT8wwT5VcY5G54tMbSNt6uCEztM
DATABASE_JDBC_URL=jdbc:postgresql://db/postgres

# DB
POSTGRES_PASSWORD=kLTPk5Ty9K3JHykCS38YBHDTVwXkVCgjsQs7HaT8wwT5VcY5G54tMbSNt6uCEztM
PGDATA="/data"

Spin them up with docker-compose up -d --force-recreate. It’ll take some minutes until EJBCA is ready to serve you.

Some notes:

  • Add 127.0.0.1 ejbca to your /etc/hosts as the ejbca declared itself on ejbca hostname/domain.
  • Make sure you can access https://ejbca/ejbca/adminweb/ without problem.

Issuing Root CA

  • On EJBCA Admin Web interface, go to CA Functions -> Certificate Authorities.
  • On Add CA form, write your Root CA common name, e.g. AgunoRootCA, then click Create
  • You’ll be redirected to complicated form of issuing CA.
  • Leave the default values as is except for:
    • CA Serial Number Octet Size: 20
    • Validity: set it to 10y
    • Issuing Distribution Point on CRLs: Use
    • Default CA defined validation data: click all Generate buttons in this section, then change the localhost strings to ejbca.
    • Monitor if CA active (healthcheck): Activate
  • Then click Create button.
  • At this point, you have two CAs:
    • ManagementCA
    • AgunoRootCA

Issuing Intermediate CA

  • Do the same again as above except:
    • The CA name is AgunoIntermediateCA
    • Leave the default values but set some values as above and:
      • CA Certificate Data, Signed By: AgunoRootCA
  • At this point, you have three CAs:
    • ManagementCA
    • AgunoRootCA
    • AgunoIntermediateCA

Preparing Certificate Profiles

Any attempt of issuing new certificate will require a certificate profile that define what kind of certificate that will be created. Let’s assume that we want to create certificate profile for high education institutions and it will be used to signing ijazah. Let’s name it HIGHEDUINSTITUTION.

  • On EJBCA Admin Web interface, go to CA Functions -> Certificate Profiles.
  • At the end of the list, enter your profile name, HIGHEDUINSTITUTION, click Add
  • It’ll be added to the list, now click Edit button as we need to modify some values. IMPORTANT NOTE: If you want to multiple select some values, press and hold Shift button or the previous selected values will be loss.
  • Now please set some values on this field :
    • Available Key Algorithms: select ONLY RSA, we need to make it broadly compatible.
    • Available Bit Lengths: select ONLY 4096 bits
    • Validity or end date of the certificate: 5y
    • Extended Key Usage: Use, Critical, select ONLY PDF Signing
    • Available CAs: select ONLY AgunoIntermediateCA
  • Click Save button

Preparing End Entity Profile

Certificate Profile defines the technical aspects of the certificate. On the other hand, EEP defines the entity aspects that related to identity.

  • Go to RA Functions -> End Entity Profiles
  • On Add Profile form, type your profile name, e.g. HIGHEDUINSTITUTION (same as the certificate profile name), then click the Add button.
  • After it added to the list, click the item then click Edit End Entity Profile button.
  • You’ll be redirected to (again) a complicated form. Leave it as is but modify some values:
    • Password: Required
    • Other subject attributes: Remove all attributes
    • Default Certificate Profile : HIGHENDINSTITUTION
    • Available Certificate Profiles: select ONLY HIGHENDINSTITUTION
    • Default CA: AgunoIntermediateCA
    • Available CAs: select ONLY AgunoIntermediateCA
    • Default Token: P12
    • Available Tokens: select ONLY P12
  • Click save
  • At this point, you have three CAs, a configured certificate profile and a configured entity profile. You’re ready to enroll new certificate for education institutions.

Let’s try to issuing and enrolling a new certificate for education institution

  • On EJBCA Web Admin interface, go to RA Functions -> Add End Entity
  • On End Entity Profile field, select HIGHEDUINSTITUTION, the form will be adjusted according to our end entity profile configuration.
  • Enter your entity information, e.g.:
    • Username: ugmacid
    • Password: enter the password for enrollment
    • E-mail address administration@ugm.ac.id
    • CN/Common name ugmacid
  • Leave other values as is.
  • Click Add button.

Let’s enroll the certificate

  • Go to https://ejbca/ejbca/, this is the public interface of the EJBCA instance.
  • On Enroll section, click Create Browser Certificate
  • Enter the username and Enrollment code (password)
  • You’ll be asked for confirmation, click Enroll button
  • A P12 file will be downloaded to your computer, it’s protected by passphrase. Use the password as passphrase.

At this point, you may check the new issued certificate against the certificate chain.

Next post

I’ll write about authentication, roles and security on maintaining EJBCA instance.

Cara Menginstall Python 3.6 di Debian 9 (stretch)

Debian 9 (stretch) secara default membawa python2.7 (default) dan python3.5. Saya sedang melakukan instalasi aplikasi yang ternyata membutuhkan Python versi 3.6. Pada beberapa tutorial di internet, menyarankan untuk menggunakan repo debian testing. Namun saat tulisan ini dibuat, saya cek repo debian testing memiliki python versi 3.8, sedangkan versi tersebut ketinggian....

Mengunci Versi aplikasi di CentOS

Setelah catatan sebelumnya kita berhasil downgrade versi aplikasi di CentOS, ternyata saat kita lakukan yum update, aplikasi kembali dinaikkan versinya ke versi yang lebih baru. Tentunya hal ini menjengkelkan karena aplikasi project kita akan kembali error alias tidak jalan. Namun jangan khawatir, pada postingan ini kita akan membahas bagaimana cara...

Cara Downgrade Aplikasi di CentOS

Sebuah aplikasi yang ditulis oleh temen-temen developer terkadang hanya kompatibel dengan versi runtime tertentu pada bahasa pemrogramannya. Hal ini akan menuntut administrator agar dapat menyesuaikan dengan kebutuhan tersebut. Nah, catatan ini disimulasikan dijalankan di sebuah VM dengan sistem operasi CentOS 8. Catatan ini juga berdasarkan pengalaman penulis saat menangani sebuah...

Multi Machine Vagrant dengan Vagrantfile Tunggal

Vagrant merupakan sebuah tools yang saya gunakan untuk provisioning Virtual Machine, khususnya untuk environment lokal di laptop. Vagrant juga dapat digunakan untuk provisioning VM dengan beberapa provider, antara lain VirtualBox, VMware, Docker, Hyper-V, maupun custom. Saya sendiri menggunakan provider Libvirt :D Oke, salah satu alasan kenapa tulisan ini saya buat...

Cara Install Autoscaling GitLab Runner yang Hemat Biaya

Ngomong-ngomong soal GitLab tidak lepas soal CI/CD (Continuous Integration/Continuous Delivery/Deployment). Nah, kebetulan Di tempat saya bekerja menggunakan gitlab-runner. GitLab Runner merupakan salah satu fitur yang sangat bermanfaat untuk menjalankan CI/CD. Saya tidak akan menjelaskan apa itu CI/CD di sini (mungkin akan saya jelaskan di postingan yang lain). Hanya akan saya...

Menjalankan Vagrant Provider Libvirt di openSUSE Leap 15.2

Melihat pak Andi Sugandi menggunakan vagrant untuk menyediakan lab VM saat beliau mengajar, saya pun jadi penasaran. Karena provisioning VM menggunakan vagrant ini sepertinya mengasyikkan, terutama karena….. Nanti deh saya ceritain apa, dan mengapa ini penting saya utarakan. Apa itu Vagrant? Tampilan Website Vagrant Vagrant merupakan sebuah perangkat lunak yang...

Cara Install gcloud CLI di openSUSE Leap 15.2

Postingan kali ini akan sangat singkat, karena merupakan catatan yang dibuat untuk sekedar mendokumentasikan apa yang saya ketikkan saat memasang gcloud CLI di laptop saya. Sistem Operasi yang digunakan di laptop saya seperti yant tertulis di judul tulisan ini, yaitu openSUSE Leap 15.2. Sebelumnya, mungkin perlu juga saya tulisan apa...

openSUSE Leap 15.2 di Google Cloud Platform (GCP)

Sebagai pengguna openSUSE, saya kadang merasa penasaran apakah bisa saya menggunakan os ini di langit sebagai server. Yang saya maksud di langit di sini adalah Google Cloud Platform (GCP), karena saya juga pengguna produk google tersebut di beberapa proyek milik klien. Namun melihat daftar templat citra (image template) di Google...

Pi Zero sebagai Tukang Periksa (Bot)

Bojongbot - Pi Zero

Saya memasang beberapa cctv berbeda merek, baik yang berjenis ip cam maupun yang analog dengan dvr. Kesemuanya terhubung ke 1 server shinobi video yang pernah saya tulis di artikel sebelumnya. Nah, beberapa perabotan itu tentunya memiliki IP, dan ada beberapa yang suka ngambek, gak hidup. Di-ping juga gak respon. Agak susah kalau tidak mengetahuinya. Kapan hari ada insiden panci presto meledak, namun cctv di area dapur pas heng. Jadi tidak ketahuan prosesnya.

Setelah kemarin ngoprek-ngoprek ARM (lagi setelah sekian lama), saya jadi inget punya beberapa perabotan arm yang tidak kepakai, salah satunya pi zero. Ya sudah itu aja dimanfaatkan jadi mesin bot. Tugasnya cuma kirim ping ke beberapa perangkat yang ada di daftar, jika gak ngasih balikan, ngirim pesan ke telegram via bot telegram.

Kodenya ada di https://github.com/princeofgiri/bojongbot.

Bot beraksi

Ada beberapa yang nanya, kenapa gak pakai ESP32 aja? Jawabannya sebagai berikut:

  1. Saya belum pernah ngoprek ESP32, baru order, belum datang saat tulisan ini dibuat
  2. Memanfaatkan yang sudah ada, jadi tinggal pakai gak perlu beli-beli
  3. Saya sangat familiar dengan linux dan bash, jadi ndak ribet bahasa pemrograman lainnya

Kepinginnya sih nanti botnya jadi tambah pinter, kulkas di rumah sepertinya ada API, bisa diintip nanti-nanti.

LibreOffice 7.0 di Raspberry Pi OS

Setelah kemarin bikin video Armbian dengan LibreOffice 7.0 (https://www.youtube.com/watch?v=1rTrCVgGXfA) ngoprek disela-sela kesibukan masih berlanjut. Kali ini ngidupin layar 7 inch dengan perangkat raspberry pi buat mainan bocah dengan GCompris.

Di Raspberry Pi OS (dulu Raspbian), yang berbasis debian buster. Caranya cukup mudah, pasang flatpak, pasang libreoffice dari flatpak. Beres!

Eh tunggu dulu, belum beres. Karena menu aplikasi libreofficenya belum bisa muncul. Harus digosok dulu. Berikut cara nggosoknya:

  • Edit berkas

/etc/xdg/lxsession/LXDE-pi/desktop.conf

  • Di paling bawah, tambahkan

[Environment_variable] XDG_DATA_DIRS=/var/lib/flatpak/exports/share:/home/pi/.local/share/flatpak/exports/share:/usr/local/share/:/usr/share/raspi-ui-overrides:/usr/share/:/usr/share/gdm/:/var/lib/menu-xdg/

  • Reboot

Udah deh!

LibreOffice 7.0 di Raspberry Pi OSLibreOffice 7.0 di Raspberry Pi OS

Unduh Buku Digital Gratis

Halaman ini sengaja penulis buat untuk kumpulan buku digital yang sudah penulis rilis dan bagikan gratis.
Silakan klik pada masing-masing judul buku untuk menuju link download



Cara menjadi Sponsor pada buku yang akan terbit


Clicks to balance

One of the things that I am sure I will miss when moving back to Indonesia is how convenient it is to do bank-related transactions in The Netherlands. Almost everything, if not all, is already connected and standardized. There is no need for virtual accounts, going through e-wallet from startups, dealing with transaction cost, etc because there is a widely approved payment system called iDEAL. Every time I go for online shopping, this is the only logo I need to see to be sure that I can do business with the shop.

This is probably one of a series of posts comparing banking in Indonesia and The Netherlands. First, we will see what it takes to do one of the most important task, in my view, in an online banking site/app: Checking the balance. I consider this to be a common task but apparently different banks have gone different routes to provide this very basic information.

I will be comparing different banks that I have access to: BNI, BCAJenius, HSBC, ABN AMRO, and Bunq. The number to measure here would be the number of clicks I need to do after the login page to see the current balance. What I show here is from what I gather on the 28th of June 2020.

BNI Desktop Web

BNI Internet Banking requires you to do 2 clicks “Rekening” and then “Saldo Rekening” to see a supposedly list of accounts and the balances.

1_o6atev462exmp_8jtmoh2w

 

BNI Mobile Web

The mobile web version, on the other hand, requires you to do 6 clicks (or 7 depending on how many accounts you have I guess), to get into the balance page.

The wording is consistent to the desktop version and the important bits are put at the top which helps the navigation.

1_jipl5cmsdloz9qfje9i3nw

BNI Mobile App

Apparently to login I need to enter the number from the ATM card. I will skip this since I am too lazy to find the card 😂

BCA Desktop Web

This old school looking page (I think they take if it ain’t broke, don’t fix it mantra religiously) requires you to go to “Account Information” page and then “Balance Inquiry” and thus needs 2 clicks.

The menu wording is probably clear enough but the first menu is put at the middle of big list of options. For me, that rarely use this page, I have to remind myself of what the menu option is. Also, the small text size does not help me at all.

bca

BCA Mobile Web

Short of similar to the desktop version, this one requires 2 clicks: “Informasi Rekening” and then “Informasi Saldo” (same wordings as above but different language — probably just my settings). The first menu is also not put up front but fortunately the list is smaller.

bcam2

BCA Mobile App

The mobile app version follows almost the same steps with an additional PIN entry page before getting into the final balance page. However, unlike both desktop and mobile web versions, the required 3 clicks are on the items put at the top.

bcaa

Jenius Mobile App

Unlike the above banks, this mobile app only bank shows the balance up front immediately after the login page. For me who consider checking the balance amount an important task to do, this really saves my time.

1_yw1ltdtdi8pz-u86hylkza

HSBC Desktop Web

HSBC also puts the balance information on the first page after you login. Zero clicks needed.

1_zi0xh3px8zzuvpuk2kd2nq

HSBC Mobile App

This version of HSBC online banking also shows the accounts and balances on the first page.

1_8tvupqoxucjax5qk7cyuzq

ABN AMRO Desktop Web

ABN AMRO also shows all bank accounts and the balances immediately after the login process.

1_rfv8jtsguetrpil8vmgypw

ABN AMRO Mobile App

Same as the desktop version, accounts and balances up front.

1_rr8l_iatmvxh3lywrj5sbg

Bunq Mobile App

Bunq is probably my favorite bank so far in terms of user experience. As expected, it also shows all accounts and balances on the first page.

1_iclr9hee2gectjlm1sccfa

Bunq Desktop Web

Following the same pattern as the mobile app’s, the Desktop Web version shows all accounts and the balances.

1_1bwf5redxabfwgxjdjievg

Conclusion

If I can take any conclusion at all, I think Indonesian banks have to step up their game and give user experience more priority. Jenius is an exception here and it’s really a breath of fresh air.

Server CCTV dengan Shinobi Video – Bag. 5, IP Cam Murah Meriah

Setelah liat-liat di situs perbelanjaan daring, saya menemukan satu kamera yang fiturnya cukup pas untuk disambungkan dengan Shinobi, harganya juga berkisar 250 ribu rupiah. Berikut fitur yang penting untuk digunakan:

  • Onvif
  • AUTO TRACKING
  • PTZ Rotate Pan Tilt 360
  • Ada sensor suara, sensor gerak dan pemberitahuan ke Hp
Mini CameraMini Camera

PTZnya juga berhasil tersambung dengan Shinobi. Onvif devicenya dikenali bikinan Eyeplus.

Server CCTV dengan Shinobi Video – Bag. 4, Menyambungkan dengan DVR

Saya memiliki satu set CCTV beserta DVRnya. Mereknya Nathans, sponsor dari kantor (PT SKK). Ini CCTV asli ndak pakai ribet, just work. Nah … PRnya adalah gimana caranya nyambungin ke Shinobi. Berminggu-minggu saya gak berhasil menemukan solusinya. Sampai saya menyerah.

DVRDVR

Sekitar 2 mingguan lalu, saya tiba-tiba nemu sebuah saran url rtsp dari internet. Dan saya coba beneran bisa. Berikut urlnya:

rtsp://192.168.0.3:554/user=admin&password=passwordmu&channel=1&stream=1.sdp?real_stream–rtp-caching=100

Silahkan sesuaikan alamat IP beserta akun yang ada di DVR Anda.

Vortex Tab 75 Programming Guide

I need to write it down here so there will be no need to visit Vortex Gears’s incomplete documentation in the future.

Programming

  • Plug in the cable, you need the LED to guide you
  • PN + LEFT_CTRL (original position) to enter programming mode
  • Press the key that want to be programmed
  • Press the target key
  • PN to apply
  • PN + LEFT_CTRL to exit

It’s possible to lose a key. Sometimes you need to backup it first. Be careful.

Reset

  • Reset the current layer key-codes: Hold PN + R (original position)
  • Reset all layers’ key-codes and restore it to default: Hold LEFT_ALT + RIGHT_ALT (original position)

Bluetooth

  • PN + LEFT_ALT (on the left of the space bar key) for 3 seconds
  • PN + J or K or L (current position)
  • Pair the device

Fn swap

  • Hit FN + LEFT_SHIFT for 3 seconds then select new FN key directly

Pn swap

  • Hit PN + LEFT_SHIFT for 3 seconds then select new PN key directly

Layer

  • PN + M or < or > (original position), indicator on left LED.

Layout

  • PN + RIGHT_SHIFT (cycle) to change layout, indicator on right LED. No LED for Qwerty, red for Colemak, green for Dvorak

Operating system

  • PN + Q or W or E (original position) for Windows, Mac and Linux respectively

Vim's Native Multiple Cursors Feature

Sublime Text was my favourite text editor, I’ve been following it since its early days. The feature I most liked and can’t live without is the multiple cursors selection. Sublime Text lets you to select and edit string on multiple place at once based on pattern that you defined. I think it was a pain killer feature. The thing was that I always want to go back to Vim. The day I found this repository (https://github.com/terryma/vim-multiple-cursors), I switched back to Vim. vim-multiple-cursors is easy and intuitive as Sublime Text’s althought it has a bit differential. But nowdays vim-multiple-cursors has been broken, especially on the latest Vim release.

I were wondering if there is a way to do the same things with Vim’s internal command. Tada yada thanks to https://vim.fandom.com/wiki/Vim_Tips_Wiki. Not very intuitive as Sublime Text’s or vim-multiple-cursors but it works as intended. Actually it is not a multiple cursors thing, still and all it achieved the same as multiple cursors feature. It’s more like a multiple replay.

Vertical multiple replay

  • Ctrl+v to vertical select your lines, use jj to expand your selection.
  • Hit Shift+i then type the string you want to insert.
  • Pres Escape, the inserted text will be appears on all lines.

Multiple replay by pattern

  • Search your string with /stringyouwanttomark
  • Type cgn then type the new string.
  • Hit Ctrl-c to exit to visual mode.
  • Press . to replay it to the next one.

Update:

This repo showed up in vim-multiple-cursors’s issues (https://github.com/mg979/vim-visual-multi) and it works good too but I think I do stay on native Vim command so I don’t have to rely on my dotfiles for this feature.

UNK rev1 Trackpoint Module

As a person who have been using Thinkpad computers for years, I was always missing the trackpoint feature. I want to type on mechanical keyboard but also I don’t willing to dismiss the nipple. There are few solution for this issue: UHK, Tex Yoda, Tex Shinobi. These all are expensive keyboard, the shipping cost alone is crazy.

Trackpoint module is one of my goals while building UNK and I successfully build it. Here is the video if you wonder how it looks/works.

If you prefer to see it in pictures: https://imgur.com/gallery/cKV1syE

The trackpoint sensor is taken from a dead Thinkpad X201 keyboard. I was planning to make a magnetic detacable connector to the right half of the keyboard, just like magsafe but I didn’t success. So, I’m using another Pro Micro instead. It’s not perfect but it’s my build and I’m happy with it.

My First Custom Handwired Keyboard Build: UNK

More detail and build logs : https://github.com/herpiko/unk

Design Process

TO BE WRITTEN

Tensorflow GPU on Nvidia 1660 Ti

Although my GPU is not listed here, I can confirm that 1660 Ti works. The machine learning training is now significantly faster than using CPU.

➜  imagerec git:(updated-deps) ✗ nvidia-smi
Tue May  5 15:00:40 2020       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.33.01    Driver Version: 440.33.01    CUDA Version: 10.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 166...  On   | 00000000:01:00.0  On |                  N/A |
| 32%   35C    P8    12W / 130W |    293MiB /  5941MiB |      2%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1549      G   /usr/lib/xorg/Xorg                            18MiB |
|    0      1953      G   /usr/bin/gnome-shell                          48MiB |
|    0      2592      G   /usr/lib/xorg/Xorg                           108MiB |
|    0      2725      G   /usr/bin/gnome-shell                         114MiB |
+-----------------------------------------------------------------------------+
➜  imagerec git:(updated-deps) ✗ python
Python 3.7.7 (default, May  5 2020, 04:20:38) 
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from tensorflow.python.client import device_lib
2020-05-05 15:01:16.900600: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libnvinfer.so.6
2020-05-05 15:01:16.901543: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libnvinfer_plugin.so.6
>>> device_lib.list_local_devices()
2020-05-05 15:01:21.071110: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2020-05-05 15:01:21.100259: I tensorflow/core/platform/profile_utils/cpu_utils.cc:94] CPU Frequency: 3692985000 Hz
2020-05-05 15:01:21.100906: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x55d1bb829330 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-05-05 15:01:21.100968: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
2020-05-05 15:01:21.105053: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcuda.so.1
2020-05-05 15:01:21.217053: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:981] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2020-05-05 15:01:21.217492: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x55d1bb8b7590 initialized for platform CUDA (this does not guarantee that XLA will be used). Devices:
2020-05-05 15:01:21.217525: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): GeForce GTX 1660 Ti, Compute Capability 7.5
2020-05-05 15:01:21.217760: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:981] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2020-05-05 15:01:21.218479: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1555] Found device 0 with properties: 
pciBusID: 0000:01:00.0 name: GeForce GTX 1660 Ti computeCapability: 7.5
coreClock: 1.86GHz coreCount: 24 deviceMemorySize: 5.80GiB deviceMemoryBandwidth: 268.26GiB/s
2020-05-05 15:01:21.218590: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudart.so.10.1
2020-05-05 15:01:21.218654: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcublas.so.10
2020-05-05 15:01:21.220646: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcufft.so.10
2020-05-05 15:01:21.221035: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcurand.so.10
2020-05-05 15:01:21.223176: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcusolver.so.10
2020-05-05 15:01:21.224561: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcusparse.so.10
2020-05-05 15:01:21.224651: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudnn.so.7
2020-05-05 15:01:21.224857: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:981] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2020-05-05 15:01:21.225935: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:981] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2020-05-05 15:01:21.226839: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1697] Adding visible gpu devices: 0
2020-05-05 15:01:21.226907: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudart.so.10.1
2020-05-05 15:01:21.443386: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1096] Device interconnect StreamExecutor with strength 1 edge matrix:
2020-05-05 15:01:21.443435: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1102]      0 
2020-05-05 15:01:21.443446: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1115] 0:   N 
2020-05-05 15:01:21.443650: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:981] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2020-05-05 15:01:21.444083: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:981] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2020-05-05 15:01:21.444563: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1241] Created TensorFlow device (/device:GPU:0 with 5176 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1660 Ti, pci bus id: 0000:01:00.0, compute capability: 7.5)
[name: "/device:CPU:0"
device_type: "CPU"
memory_limit: 268435456
locality {
}
incarnation: 7827239615455337760
, name: "/device:XLA_CPU:0"
device_type: "XLA_CPU"
memory_limit: 17179869184
locality {
}
incarnation: 9475332420332566901
physical_device_desc: "device: XLA_CPU device"
, name: "/device:XLA_GPU:0"
device_type: "XLA_GPU"
memory_limit: 17179869184
locality {
}
incarnation: 11551463581523616297
physical_device_desc: "device: XLA_GPU device"
, name: "/device:GPU:0"
device_type: "GPU"
memory_limit: 5427691520
locality {
  bus_id: 1
  links {
  }
}
incarnation: 634448236828243524
physical_device_desc: "device: 0, name: GeForce GTX 1660 Ti, pci bus id: 0000:01:00.0, compute capability: 7.5"
]
>>> 

Using CPU,

python train.py  32,29s user 6,06s system 333% cpu 11,514 total

Using GPU,

GPU=1 python train.py  7,73s user 2,09s system 109% cpu 8,959 total

The setup is quite complex with various errors and version missmatches. I let myself to symlink different version of CUDA/cuDNN libraries.

If you’re planning to buy a GPU to support your machine learning project, pick a RTX graphics card. It’s tremendously faster with built-in tensor cores. Unlimited budget? Here you go.

I Spilled Coffee on My Mechanical Keyboard

My main keyboard was a Vortex Core. After my wife keep complaining about the noises (now you know it’s the blue one), I bought a Vortex Tab 75 with Cherry MX brown switches (she approved the new typing sound). It’s just a few weeks before I made an accidental disaster to the keyboard.

I was programming on some stuff while snacking Dua Kelinci peanuts. The peanuts were in a small plastic jar on the left of my keyboard. Also, there is a cup of coffee near there. I eat the peanuts by pouring them to my hand, then forwarded the peanuts to my mouth. These actions were done above the keyboard. Then I unconsciously grab the coffee cup and do the same as I thought it’s the peanut jar. So I just literally poured my hand with coffee and the fluid flood the keyboard!

What I’ve done to solve this:

Go to forums and read some advices

Most of the sources I found were from https://www.reddit.com/r/MechanicalKeyboards/.

Prepare some stuff

  • Screwdriver
  • Key puller
  • Solder
  • Vacuum desoldering pump
  • Tin
  • Alcohol
  • Cotton bud

Unplug it and/or turn it off

I grab the keyboard fast, unplugged the cable + batteries, then turned it upside down. Even if the keyboard uses a low voltage to operate, circuit short can causes a problem.

Pull all the keycaps

You need key puller. Full them all carefully.

Take apart and dried the board in a night

I put the board on top of a fan and left it for a night to make sure there is no fluid left behind.

Test it

The next morning, I plugged the keyboard into my computer and tested it. All the keys were worked as intended but some switches went bad. They felt terrible on my fingers. It may be easy for me if I poured plain water instead of coffee. My coffee contained a bit of sugar and it makes a big difference in how the switches feel. Sugar can make your switches sticky. I need to clean up the dried coffee fluid that remains in the switches’ housing. The only way to do this is to desolder the switches first.

I identified the bad switches and mark them with a permanent marker then unplugged the keyboard.

Desolder the bad switches

I carefully desolder the bad switches. A vacuum desoldering pump is a must here. You can’t do desoldering properly without this tool. I think this is the hardest part.

Take apart the switches and clean it with alcohol

I took apart each switch and cleaned it with a small amount of alcohol using the cotton bud. I reassembled the switches’ housing and test it immediately to make sure it does not feel sticky again.

Resolder

I resolder the switches back to the board. For me, resoldering is far much easy than desoldering.

Test it

I tested all the keys again but with keycap on. You need to test it using keycap to get the accurate feel of the switches. All my switches turned good except the K key switch. It still a bit sticky but it’s ok for me.

Reassembly

I reassembled the keyboard to its original shape. All was well.

UPDATE: 20200607

Turned out that the sticky K key became worse and it’s not ok for me because I used it intensively to navigate in Vim. Instead of fixing this particular one, I decided to replace the entire letter keys with Gateron brown switches. Gateron switches feel smoother than Cherry MX although I can’t overcome the difference while fast typing.

Here is a time-lapse video of me replacing the switches,

Data Diri Lengkap di Marketplace

Maraknya penjualan data yang dicuri dari marketplace sedikit banyak tidak lepas dari penggunanya juga, makanya sampai saat ini kalau ada notifikasi peringatan untuk melengkapi data diri (No KTP, KK, dll.) saya tidak melakukannya, termasuk dulu jamannya masih main di FJB Kaskus.

Di beberapa marketplace mensyaratkan kita harus melengkapi data diri tersebut agar akun kita bisa terverifikasi 100 %, tapi saya tetap tidak melakukan, biarlah akun saya tidak terverifikasi 100% tidak mengapa daripada data diri diperjual-belikan, resikonya sih calon pembeli yang belum begitu kenal sangsi dengan dengan reputasi toko online kita.

Segera ganti password dan PIN anda untuk mencegah kejadian yang tidak diinginkan

Satu lagi, jangan terlalu banyak membiarkan saldo kita di akun marketplace, lebih aman lagi kalau kita pindah ke rekening pribadi (walau tidak 100%).



Saatnya tarik saldo ah, kalau ada yang saldonya melimpah dan tidak punya rekening pribadi, saya tidak menolak jika anda mengirimnya ke rekening saya



Cara Install extensi redis di Azure App Service Linux

Pada proyek di salah satu klien di tempat saya bekerja, menggunakan layanan Azure app service untuk mendeploy aplikasi Laravel. Aplikasi tersebut membutuhkan ekstensi redis untuk dapat terhubung dengan cache service di azure yang berbasis Redis. Berikut langkah-langkah pemasangannya. Buka konsol KUDU https://<sitename>.scm.azurewebsites.net Pilih SSH pada konsol SSH, ketikkan perintah berikut...

Felix The Cat (1)


Buku ini cetakan kedua yang dicetak pada tahun 1928, saya temukan pada tahun 2017 di Surabaya. Harganya murah, cuma 20 ribu rupiah. Kisah yang diceritakan dalam buku ini sangat menarik, tak heran memenangi Pulitzer Prize. Umur buku ini hampir 1 abad. Buku yang paling tua yang pernah saya miliki. Tiap lembar kertasnya sangat tebal, setebal sampul buku tulis anak sekolahan, namun juga sangat rapuh. Saya menemukannya di belantara pasar Blauran, Surabaya. Buku ini terjepit di tumpukan paling bawah dari buku-buku yang mungkin tidak lagi dibaca oleh orang-orang. Kotor oleh tanah, sarang laba-laba dan beraroma tikus dan (maaf) pipis kucing. Yang pernah mengunjungi sektor buku bekas dari pasar Blauran di sekitar tahun 2015-2018 mungkin dapat membayangkan situasi yang saya maksud. Tapi bukan buku ini yang ingin saya bahas, melainkan buku lain yang diberikan sebagai bonus oleh penjual buku. Judulnya “Welcome To Felix the Cat”.


Felix The Cat sempat menarik perhatian saya karena sampulnya sangat tebal dan tidak ada nama penulis. Ketika saya buka, ternyata isinya tulisan tangan. Setelah saya bolak-balik dan baca cepat, saya menyadari bahwa ini adalah buku harian. Saya membiarkan buku itu dimasukkan ke kantong belanja saya.

Saya membaca separuh isi buku itu sepanjang perjalanan balik ke Jakarta. Setelah sampai di Jakarta, saya malah terbersit keinginan untuk kembali lagi ke Surabaya, mencari penulis buku ini.

Bersambung.

Screencast OBS Studio ke Google Meet di openSUSE

Saat ini masanya, masa pandemi ini banyak yang melakukan pekerjaan dari rumah (“WFH”). Salah satu kebutuhan saat meeting secara daring adalah melakukan screencasting, atau berbagi layar. Catatan ini menjelaskan bagaimana cara melakukannya dengan OBS Studio dan Google Meet. OS yang saya gunakan di laptop adalah openSUSE Leap 15.1. Yang perlu...

Xcode Not Enough Disk Space to Install

I need to update my Xcode on my MacBook Air, it only has 128 GB Flash Storage, and it is hard to upgrade the storage, obviously it has limited free storage, so I need to free some spaces, deleting my old files.

But, even there is already 23 GB free storage, it keep complaining, not enough disk space.

After I had 26 GB free storage, I can continue the update.

Membuat CI/CD di GitLab CI

Sekarang saatnya saya akan membuat sebuah catatan tentang bagaimana kita akan membuat CI/CD (Continuous Integration & Continuous Delivery/Deployment) di GitLab. Ini merupakan contoh sederhana yang mungkin dapat Anda jadikan acuan jika Anda sama sekali baru dalam dunia CI/CD, khususnya di GitLab CI. Istilah-Istilah Penting Hal pertama yang ingin saya jelaskan...

Raise/Lower Hand on Zoom Cloud Meeting

Raise/Lower Hand on Zoom Cloud Meeting is a very useful feature.

During online meeting, or online class using Zoom, not all participant can talk at the same time, sometimes the host will mute all participants, when participant want to interrupt, or asking something, so they need to raise the hand.

It seems like not all Zoom user have Raise/Lower Hand icon on the main window, the easiest way to do so is using short cut, for Mac user, the shortcut is: `option + y`.


Install GitLab Runner dengan Ansible

Setelah kita selesai menyiapkan server GitLab di postingan sebelumnya ini dan/atau ini, selanjutnya akan kita setup server atau instance untuk digunakan sebagai Runner. Apa itu GitLab Runner? GitLab Runner merupakan aplikasi sumber terbuka yang digunakan untuk menjalankan job dan mengirim kembali hasilnya ke GitLab. Sebagai penghubung dengan GitLab CI, layanan...

Server CCTV dengan Shinobi Video – Bag. 3, Menggunakan IP Cam Publik

Bagaimana kalau mau belajar pemasangan shinobi namun tidak memiliki IP Cam? ada caranya kah?

Ada. Pasti Ada

Salah satu caranya adalah dengan menggunakan IP Cam publik yang berada di beberapa wilayah/negara. Daftarnya bisa didapat di http://www.insecam.org/. Tidak semua bisa digunakan, namun tentu saja ada yang bisa. Saya sendiri menemukan satu yang sukses digunakan. Tahapannya kurang lebih seperti ini:

  1. Cari salah satu kamera. Saya menemukan yang berada di Jepang. http://www.insecam.org/en/view/534370/.
  2. Ambil IP Addressnya, investigasi url-urlnya dengan iSpy agar bisa mendapat informasi lebih detil.
  3. Jika tanpa nomor 2, juga bisa, kebetulan kameranya support ONVIF, tinggal masukin alamat IP dan atur-atur dan coba-coba sampai pas
  4. Khusus ini, saya menemukan bahwa konfigurasi yang pas itu MJPEG.
IP Cam PublikIP Cam Publik

Selamat mencoba dan latihan untuk kamera yang lain. Banyak spot-spot bagus juga lho.

 

PS: CCTV Xiaomi Yi Max 02 1080p Outdoor Smart IP Cam ini ndak support ONVIF gak bisa diakses via rtsp jadinya.

Server CCTV dengan Shinobi Video – Bag. 2, Pemasangan Shinobi

Pemasangan Shinobi cukup mudah sekali, cukup menjalankan sebaris perintah dari root:

bash <(curl -s https://gitlab.com/Shinobi-Systems/Shinobi-Installer/raw/master/shinobi-install.sh)

Selanjutnya tinggal mengikuti langkah-langkah yang ada di layar. Saya memilih mengambil dari branch development agar mendapatkan fitur-fitur terbaru sekaligus testing. Dokumentasi pemasangan secara lengkap bisa dibaca di sini.

Berikut hal-hal utama yang perlu dilakukan setelah pemasangan:

Peramban Firefox

Gunakan peramban Firefox. Karena peramban Chrome tidak mau bila ada https dan self sign. Juka untuk streaming beberapa video cctv. Firefox bekerja lebih benar dari pada Chrome. Enggak tau kenapa.

Masuk sebagai admin dan buat user

Kita perlu memasukkan url http://alamat-ip-shinobi-server:8080/super. User / Pass bakunya adalah admin@shinobi.video / admin. Dari halaman ini kita bisa membuat user baru untuk masuk ke dashboard shinobi server. Juga untuk mengganti password akun admin tersebut.

Super AdminSuper Admin

Shinobi Dashboard

Untuk masuk ke dashboard, buka peramban dan arahkan ke http://alamat-ip-shinobi-server:8080/ lalu masukkan username/password yang sudah dibuat tadi.

Menambahkan Kamera

Klik tombol + (Add Monitor). Di sini kamera disebut monitor. Lalu tinggal isikan parameter-parameter yang sesuai kamera. Saya mencoba sendiri dan ribet. Setelah beberapa kali percobaan, baru berhasil.

Menambah KameraMenambah Kamera

Ada cara gampangnya, melalui menu pojok kiri atas – ONVIF. Lalu isikan alamat ip dan klik tombol search. Secara pintar, shinobi bisa mendeteksi kamera dalam jaringan yang kombatibel ONVIF. Jika ketemu, akan ditampilkan deskripsi kamera, bahkan bisa tahu merek/modelnya. Lalu tinggal klik tombol bergambar 2 dokumen (seperti ikon duplicate).

Add Monitor - ONVIFAdd Monitor – ONVIF

Selanjutnya tinggal melengkapi/mengganti isian yang ditampilkan (sama dengan jendela Add Monitor). Tinggal disesuaikan saja atau langsung Save. Secara baku, kamera akan memiliki mode View Only. Kita bisa mengatur/mengganti modenya menjadi Record.

Dua Kamera/MonitorDua Kamera/Monitor

Power Video Viewer

Digunakan untuk melihat video yang sudah tersimpan terekam. Tombol ikonnya mirip seperti tag/point pada peta.

Video ViewerVideo Viewer

Seingat saya, Power Video Viewer ini yang tidak bisa di Chrome.

Dah itu dulu tulisan kali ini. Tulisan berikutnya saya akan jelaskan cara optimasinya.

 

*Featured image diambil dari http://getwallpapers.com/collection/hidden-leaf-village-wallpaper

Install GitLab dengan Ansible

Nah, kemarin sudah kita bahas instalasi GitLab secara manual di postingan sebelumnya. Kali ini saya akan tuliskan langkah-langkah instalasi GitLab dengan cara yang lebih simple, yaitu dengan Ansible. Ansible adalah sebuah alat otomasi yang dikembangkan oleh RedHat. Beberapa kata kunci yang melekat pada Ansible adalah “automation tool”, “configuration management”, “infrastructure...

Server CCTV dengan Shinobi Video – Bag. 1, IP Cam

Oprekan kali ini bermula dari lokasi proyek rumah yang kemalingan. Saat awal bangun, kemalingan genset, berikutnya beberapa minggu lalu, para tukang kemalingan handphone.

Saya memiliki cctv yang ada di rumah, subsidi dari Pak Bos yang memiliki perusahaan penjualan cctv. Yang sudah dipakai, sangat mudah dioperasikan. Just work. Namun kali ini sejak pandemi, saya kepikir untuk memanage cctv tersebut dengan linux, entah raspi atau pakai komputer-komputer spek rendah.

Sebelumnya, saya sama sekali tidak mengerti teknologi cctv beserta perabotannya. Namun sejak ngoprek ini, pengetahuan jadi bertambah. Awalnya hanya tau/nemu Shinobi Video saja, setelah itu bingung, harus bagaimana? cara koneksinya ke cctv bagaimana?

Dinamakan IP Cam, tentunya memiliki IP, umumnya, dari pabrikan diatur menjadi dhcp client. Sehingga dapat IP otomatis dari router/server dhcp. Saya dipinjami IP Cam oleh Pak Iwan Tahari. Dalam kardusnya tidak ada informasi apapun (buku manual juga tidak ada). Merek/Pabrikan pembuatnya juga tidak tahu. Jadi dengan coba-coba colokin aja ke router/modem yang ada di rumah, lalu diintip dapat IP berapa, nah itu dia tinggal dipanggil IPnya di peramban.

IP CamIP Cam

Setelah sukses dapat IP, saya punya 1 komputer yang rencananya jadi server cctv dan sudah ada dhcp servernya, saya sambungkan IP Cam tersebut ke komputer . Dapat IP 10.42.0.151. Tinggal dipanggil di peramban dan muncul antar muka web si kamera.

Antarmuka WebAntarmuka Web

Hal utama yang perlu dilakukan adala mengatur zona waktu/waktu, agar nantinya saat dipakai, timestamp yang ditampilkan sesuai. Hal berikutnya adalah pengaturan kualitas gambar. Kamera ini sanggup merekam video/gambar dengan codec H265 dan H264, juga bisa merekam audio serta pengaturan fps dan kualitas. Saya mengatur kualitas medium dan codec H264 (karena H265, rata-rata browser tidak mulus menampilkannya).

Selanjutnya, bagaimana cara menguji bahwa kamera tersebut bisa digunakan? Saya cukup bingung dengan pertanyaan sendiri. Mencari-cari, akhirnya menemukan jawaban, bahwa bisa menguji dengan menggunakan VLC. Tinggal memasukkan url rtp/udp melalui menu Open Network. Nah bagaimana mendapatkan urlnya? macem-macem jawabnya dan bingung. Namun saya menemukan aplikasi pembantu, yang bisa memandu kita.

Aplikasinya bernama iSpy, opensource, adanya di OS Windows saja. Cara penggunaannya cukup mudah, bisa mencari berdasarkan IP yang kita masukkan atau dia mencari melalui jaringan yang ada. Setelah itu dia akan memberikan info ke kita daftar url yang bisa digunakan.

iSpyiSpy

Ada beberapa format yang perlu diperhatikan:

  • ONVIF, ini format standar IP Cam, jika bisa ini, dengan Shinobi bisa otomatis dalam pendeteksiannya.
  • RTSP, catat url rtsp yang diberikan, di atas contohnya rtsp://ip:8554/live/ch00_0
VLC dengan rtspVLC dengan rtsp

Setelah sukses tampil di VLC, kita bisa melanjutkan pemasangan Shinobi Video.

Install GitLab di Ubuntu 18.04

Setelah sekian lama, saya merasa perlu memerbarui konten blog ini. Kali ini saya akan menulis ulang panduan instalasi GitLab di Ubuntu 18.04 dalam Bahasa Indonesia. Dokumentasi resminya dapat langsung diakses melalui halaman ini. Di sana cukup singkat dan mudah dipahami. Namun saya menambah beberapa cuil penjelasan tambahan berdasarkan hasil praktek...

Membuat VM dengan Ubuntu Cloud Image di KVM/virsh

PERINGATAN, Aku akan mengambil harta karunmu. Eh, bukan. Kalo disebut tutorial sebenarnya enggak juga, postingan ini lebih ke catatan pribadi. Dan mungkin akan banyak yang sulit dipahami, terutama jika pembaca belum pernah menggunakan Linux, atau belum pernah menggunakan virsh. Namun, saya akan tetap menulikan ini sebagai “tutorial” yang mungkin akan...

Pasang ulang Weibu F3C – Endless Mini PC (unreleased)

Saya mendapatkan komputer ini dari Baris, CEO Endless Solutions jaman saya masih jadi ambassador pada 2017. Sudah terpasang Endless OS dan berfungsi dengan baik. Beberapa hari ini saya memutuskan untuk mengganti OSnya dengan OS apapun yang memungkinkan.

Pengujian pertama dengan openSUSE Tumbleweed, pemasangan berjalan mulus, masuk desktop agak kacau dikarenakan layar HDMI dianggap sebagai layar extended. Jadi harus mengarahkan kursor yang tepat dan mengatur ulang layar beserta resolusinya. Setelah masuk desktop, wireless tidak bisa digunakan. ini sudah sesuai prediksi. Pasang firmware non-free juga tidak membuahkan hasil.

Pengujian berikutnya dengan Ubuntu 20.04 yang masih Beta. Hampir sama, perbedaannya hanya si Ubuntu sedikit lebih pintar mengenali layar dari pada openSUSE. Namun tetap perlu mengatur resolusi layarnya. Wireless juga sama-sama tidak bisa digunakan walaupun sudah memasang firmware non-free.

Berikutnya nyari firmware yang dipakai Endless OS, nemu di github https://github.com/endlessm/linux-firmware. Coba dipasang … jreng, tetep gagal. Karena masih penasaran, saya unduh iso Endless OS terkini, dan install lagi. Selanjutnya ambil /lib/firmware untuk dibandingkan, ternyata ada sedikit (bisa dibilang banyak sih) tambahan dari yang ada di github. Saya rangkum di https://lumbung.mycoop.id/ahmadharis/linux-firmware/commit/ee4aec2c50e82a06861e2b166814d418e3d5046b. Setelah dipasang, reboot, tetep gak mau.

Baca-baca dmesg, terus guling-guling, nemu titik terang untuk ambil dari https://archive.raspberrypi.org/debian/pool/main/f/firmware-nonfree/firmware-brcm80211_20161130-3+rpt3_all.deb terus dibongkar. Dicomot yang brcmfmac43455. Saya rangkum di https://lumbung.mycoop.id/ahmadharis/linux-firmware/commit/1c1f19900b2399ce123dd5e5d2978aa6ba21e397.

Dicoba di Ubuntu 20.04 sukses. Di openSUSE Tumbleweed pun demikian.

openSUSE TumbleweedopenSUSE Tumbleweed

 

Ubuntu 20.04Ubuntu 20.04

Macbook Jadul dengan openSUSE Tumbleweed

Jadi kapan hari menjenguk duo R, dan keinget kalau ada “harta” lama yang gak dipakai. Jadinya saya minta dan dicoba dihidupkan. Macbook2,1. Laptop jaman Pak Beye kata teman saya.

Macbook2,1Macbook2,1

Ini komputer cukup nyusahin. Kalau pakai MacOS X mentok di Lion. Walhasil gak bisa ngapa-ngapain, wong banyak aplikasi ndak support. Boot usb linux juga ndak mau, gak kayak Macbook keluaran baru yang mau boot linux. Dulu masang ubuntu lewat media CD. Berhubung sudah gak punya CD, alhasil menggunakan segala cara agar bisa boot. Cara termudah adalah memasang ubuntu dari komputer lain, lalu pindah disknya ke macbook jadul tersebut.

Bagaimana dengan OS Linux lainnya? susah … gak bisa kepasang. Kesimpulan akhir, karena grub yang terpasang di ubuntu itu grub-pc i386 (walaupun pakai arch 64 bit). Jadi yang mulus terpasang pertama kali adalah ubuntu.

Selanjutnya usaha agar memasang openSUSE Tumbleweed. Berbagai cara sudah digunakan, ketemu kesimpulan cara yang mujarab sebagai berikut:

  1. Pasang opensuse (boot legacy, jangan uefi) pada disk (usb flashdisk) lain dengan komputer lain.
  2. Sediakan partisi kosong ext4 di macbook jadul tersebut.
  3. Salin isi usb flashdisk pada nomor 1 ke dalam partisi ext4 tadi. Salin dengan opsi -rapv biar kebawa semua atribut dan permission berkasnya.
  4. Uji dengan chroot, kalau mulus berarti sudah benar.
  5. Ubah fstab, sesuaikan dengan uuid yang baru, pindah motherboard/komputer akan membuat beda uuid.
  6. Edit grub di ubuntu, sesuaikan.

Ribet kan? tapi seru, buat nambah kesibukan selama masa diam di rumah.

Pergi ke FOSDEM 2020

Ini nulisnya telat banget, juga males nulis banyak karena udah telat. Intinya sih pingin pamer kalau berhasil pergi ke FOSDEM 2020 di Belgia. Dan seru-seruan bersama teman-teman TDF/LibreOffice.

TDF Board & MCTDF Board & MC

 

Biar kayak orang-orangBiar kayak orang-orang

 

Konser BrexitKonser Brexit

 

Bawaan balik ke kampungBawaan balik ke kampung

Foto lainnya masih banyak sih, tapi ndak minat ditaruh di sini. 🙂
Perjalanan ini ditanggung sepenuhnya oleh The Document Foundation (kecuali pembelian oleh-oleh).

Vim Dev Containers

I’ve been using vim and docker previously, but this post that explain how to use vscode devcontainers amaze me.

Pre-Req

Before try this tutorial you should have docker and docker-compose installed.

Setup Global .gitignore

Create .gitignore_global file to ignore .containers folder

$ echo '.containers' > ~/.gitignore_global

Then enable it by configure git

$ git config --global core.excludesfile ~/.gitignore_global

Create .containers directory for your project

In this post, I will use ruby repository for example. You can clone the repository from github

$ cd workspace
$ git clone https://github.com/ruby/ruby.git

Create your .containers directory inside ruby repository

$ cd ruby
$ mkdir .containers
$ touch .containers/docker-compose.yml
$ touch .containers/Dockerfile

You will have file structure similar to this

/home/user/workspace/ruby/
    .containers
    | | docker-compose.yml
    | | Dockerfile
    other_ruby_files

Edit your .containers/Dockerfile with this

FROM ubuntu:18.04

WORKDIR /workspace

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y git ruby autoconf bison gcc make zlib1g-dev libffi-dev libreadline-dev libgdbm-dev libssl-dev build-essential tzdata

You’ll need tzdata to running timezone-related tests in ruby repository

Before create compose file, some tests in ruby refer to [::1] as localhost, which makes us to enable ipv6 in our container. Configure your docker to enable ipv6 by editing /etc/docker/daemon.json

{
    "ipv6": true,
    "fixed-cidr-v6": "2001:db8:1::/64"
}

Then reload docker with $ sudo systemctl reload docker

Edit your .containers/docker-compose.yml with

version: '3'

services:
  dev:
    build:
      dockerfile: Dockerfile
      context: ./
    sysctls:
      - net.ipv6.conf.all.disable_ipv6=0
    command: sleep infinity
    volumes:
      - .bash_history:/root/.bash_history
      - ./..:/workspace:cached

To make persistent command history in our container, we can mount .bash_history.

Build Containers

Next we need to build our containers then running it as a daemon

$ docker-compose -f .containers/docker-compose.yml build
$ docker-compose -f .containers/docker-compose.yml up -d

To compile ruby and running tests, we need to use container shell

$ docker-compose -f .containers/docker-compose.yml exec dev bash

Build Ruby and Running Tests

To build ruby we need to run several commands based on README.md files

These commands run in your docker container

root@docker-hash-container:/workspace# autoconf
root@docker-hash-container:/workspace# ./configure
root@docker-hash-container:/workspace# make

To running tests

root@docker-hash-container:/workspace# make test-all #running all tests
root@docker-hash-container:/workspace# make test-all TESTS='test/ruby/test_time_tz.rb' #running single file test

Create shortcut

If you want to connect container’s shell via vim, you can add following lines to your .vimrc

nnoremap <silent> <leader>dev :terminal docker-compose -f .containers/docker-compose.yml exec dev bash<CR>

Now you can connect to container’s shell with <leader>dev, but you should spawn your container first. I also create alias in my .zshrc for easier command

alias container='docker-compose -f .containers/docker-compose.yml'

Now you can spawn or kill container with

$ container build #for build container
$ container up -d #for running container in background
$ container exec dev bash #for connecting to container shell
$ container down #for shutting down container

What Next

Now you can still use vim as editor, and have containerized development env.

Beli Kuota Rela, Tapi Beli Aplikasi Tidak Mau

Beberapa hari lalu saya mengisi acara Seminar Pendidikan yang diselenggarakan oleh salah satu yayasan, temanya adalah "Implementasi Belajar Sambil Bermain lewat Permainan di Gawai" (kurang lebih seperti itu kalau diterjemahkan ke bahasa Indonesia).

Salah satu Materi saya adalah mengenai penggunaan GCompris untuk belajar sesuai kurikulum yang berlaku.

Pada sesi tanya jawab ada salah seorang peserta yang bertanya;
  • Apakah GCompris bisa diinstal di Android?
  • Bisa, jawab saya singkat, cari saja di Playstore
Kemudian sebagian besar peserta seminar mulai mencarinya di playstore.
Salah seorang peserta bertanya;
  • Kok berbayar?

  • Ya, jawab saya dengan beberapa penjelasan singkat
  • Peserta lain kemudian menimpali kalau harganya terlalu mahal untuk sebuah permainan.
Saya pun menjawab:
  • Dalam satu bulan anda belu kuota habis berapa?
Dia jawab
  • Kurang lebih 100 ribu untuk saya, kalau untuk anak saya 20 ribu untuk seminggu.
Kemudian saya menimpali, Anda beli kuota setiap bulan saja tidak sayang, kok beli aplikasi yang harganya cuma 99.000 dan bisa dipakai seumur Android sayang banget.
Belum lagi kuota untuk anaknya yang dipakai untuk game online yang tidak jelas unsur pendidikannya.

Padahal rata-rata peserta seminar adalah tenaga pendidik (guru), termasuk kedua peserta yang bertanya tadi.
Sepertinya tingkat Edukasi untuk tenaga pendidik di Indonesia masih perlu ditingkatkan lagi.
 

Penulis Yang Egois



Belakangan ini saya memang sedang sering berinteraksi dengan orang-orang yang bergerak di bidang Keperpustakaan atau Literasi.

Dari obrolan dengan beberapa penulis buku dalam kegiatan tersebut, saya mendapatkan fakta bahwa kebanyakan penulis tersebutnya ketika mengawali jadi penulis menggunakan aplikasi yang tidak legal.
Sebagian dari mereka sadar bahwa aplikasi yang dia gunakan untuk menulis itu ilegal.

Sebagian lagi tidak mengetahuinya sama sekali karena ketika membeli komputer/laptop aplikasi tersebut sudah terpasang.
Saat sudah menjadi penulis terkenal, sebagian sudah menggunakan aplikasi yang legal dengan membelinya.

Sebagian lagi tetap menggunakan aplikasi yang ilegal walau sudah mampu membelinya dari hasil menulis buku. Dia pun tahu dan sadar kalau yang dia lakukan tidak benar.

Ada juga yang walau sudah menerbitkan puluhan judul buku tapi tetap tidak tahu kalau aplikasi yang dia gunakan untuk menulis itu ilegal.

Padahal di semua buku yang dia tulis, kemudian diterbitkan selalu tertulis kalimat kurang lebih seperti ini  
Hak Cipta dilindungi undang-undang. Dilarang memperbanyak atau memindahkan sebagian atau seluruh isi buku ini dalam bentuk apapun, baik secara elektronis maupun mekanis, termasuk memfotokopi, merekam atau dengan sistem penyimpanan lainnya tanpa izin tertulis dari penulis.


Dia sendiri ketika menulis buku sudah melanggar hak cipta, atau menggunakan aplikasi hasil penggandaan tanpa seijin pembuatnya, lha buku yang dia tulis kok tidak boleh digandakan!
Menurut saya ini namanya penulis yang egois dan dzalim.

Pesan saya, daripada menulis dengan aplikasi ilegal karena memang belum mampu beli, lebih baik pakai aplikasi yang walau gratis tapi legal.


Fungsi Fitur Arrange di Inkscape

Salah seorang pengguna Inkscape pemula ada yang bertanya mengenai fungsi dari fitur Arangge, mungkin karena bingung cara menggunakannya, atau belum pernah mencoba menggunakannya tapi sudah bertanya duluan.

Sayangnya lagi gambar yang ia lampirkan berupa hasil foto yang kurang jelas, mungkin ia tidak tahu cara mengambil cuplikan layar (screenshot) di komputer, ya mohon dimaklumi saja.

Sebenarnya  penjelasan mengenai fitur tersebut sudah saya tulis di buku Desain Grafis dengan Inkscape versi 2 yang rencanya akan terbit setelah Inkscape versi 1.0 rilis filnal secara resmi.

Di bawah ini adalah penjelasan singkat penggunaan Arrange yang saya Salin-Tempel dari buku yang sedang saya kerjakan tersebut.


Arrange digunakan untuk mengatur beberapa object yang letaknya tidak beraturan supaya rapi, cara kerjanya adalah menata object-object tersebut membentuk kolom dan baris dengan jarak tertentu sesuai parameter yang telah dilakukan.
Jendela pengaturan Arrange dapat ditampilkan dengan klik Object => Arrange.

Pada jendela pengaturan Arrange terdapat dua Tab, yaitu Rectangluar grid dan Polar Coordinate.

Berikut contoh penggunaan pada tab Rectangluar grid:
  • Seleksi object yang akan diatur

  • Isikan nilai tertentu pada kotak Rows dan Columns (contoh: 5 x 5)
  • Lakukan pengaturan pada menu Alignment (contoh: Center) 
  • Pilih salah satu menu Fit into selection box atau Set spacing (contoh: pilih Set spacing)
  • Isikan nilai tertentu pada kotak X dan Y (contoh: 2 X 2 cm)

Jika semua pengaturan dirasa sudah selesai dan benar, klik tombol Arrange, maka hasilnya seperti gambar di bawah ini


Berikut contoh penggunaan pada tab Polar Coordinate:
  • Pilih tab Polar Coordinate
  • Pada menu Objecs' bounding boxes: pilih Center

Pada menu Arrange on pilih Parameterized, maka segera tampil submenu seperti gambar di bawah ini:


Sebagai contoh latihan, lakukan langkah seperti berikut:
  • Pada kotak Center X/Y masing-masing isi dengan nilai 20,00 cm 
  • Pada kotak Radius X/Y masing-masing isi dengan nilai 20,00 cm
  • Pada kotak Angle X/Y isi dengan nilai 0,00 dan 360, jangan lupa unitnya pilih derajat (bukan turn, rad, atau grad).
  • Beri tanda centang pada Rotate objects
Jika semua pengaturan dirasa sudah selesai dan benar, klik tombol Arrange, maka hasilnya seperti gambar di bawah ini
Demikian penjelasan singkat contoh penggunaan fitur Arrange pada Inkscape.
Sampai jumpa pada tutorial menarik lainnya.
-
Sumber:
Draf naskah buku Desain Grafis dengan Inkscape v.2



Rute Bus Salatiga - Semarang

Sebenarnya penulis sudah lama ingin membuat artikel singkat ini, namun lupa terus karena lebih banyak menulis buku.

Artikel ini hanya berupa info singkat mengenai beberapa rute bus Salatiga - Semarang jika anda ingin  menggunakan moda transportasi umum.
Penulis sengaja menulis artikel ini untuk membatu pembaca yang bingung ketika memilih bus dari Salatiga yang mau ke Semarang.
  
Jika Anda akan naik Bus umum dari Salatiga ke Semarang memang harus lebih cermat, karena terdapat 3 tujuan terminal yang beda, dan satu bus jurusan tengah kota.

Salatiga - Terminal Mangkang
Bus ini cocok jika anda akan meneruskan perjalanan ke Semarang wilayah Barat dan Utara, Misalnya ke Bandara Ahmad Yani, Ngalian (Boja), Kendal, Jakarta, dan lain-lain. Anda bisa menggunakan Bus Patas Solo - Semarang yang lewat Tol Krapyak.




Salatiga - Semarang Kota
Bus ini rutenya lewat tengah kota (membelah jalur tengah kota), sangat cocok anda naiki jika tujuan anda adalah ke Semarang kota atau tengah, Misalnya ke Tembalang, Jatingaleh, RSUD Kariadi, Tugu Muda, Poncol, Johar, Kota lama, Tawang, dan lain-lain.
Anda bisa menggunakan Bus jurusan Salatiga - Semarang yang berupa Mini Bus, dan bus ini satu-satunya yang tidak lewat tol ketika ke Semarang, namun ketika bus ini kembali ke Salatiga (rute seblaiknya) lewat tol.
Bus jurusan ini hanya berjalan antara pukul 05.00 s/d 17.00 WIB.


Salatiga - Terminal Terboyo
Bus ini cocok jika anda akan meneruskan perjalanan ke wilayah Genuk, Demak, Kudus, Rembang, Surabaya (jalur Pantura), dan lain-lain. Namun perlu diingat, bahwa saat ini sudah jarang Bus dengan juruan Terboyo, karena terminal Terboyo sudah ditutup untuk Bus Umum dan dialih-fungsikan sebagai terminal Peti Kemas.
Namun masih ada satu-dua Bus Patas Solo - Semarang yang ke Terboyo, Bus ini melewati Tol Tembalang - Kaligawe, yaitu masuk gerbang tol Sukun dan keluar gerbang tol Kaligawe. Yang perlu diingat bahwa Bus jurusan ini tidak masuk ke terminal.



Salatiga - Terminal Penggaron
Rute Bus ini sejatinya sebagai pengganti Terminal Bus Terboyo, sangat cocok jika anda akan meneruskan perjalanan ke wilayah Kudus, Pati, Purwodadi, dan lain-lain.
Bus ini melewati Tol Tembalang - Gayamsari, yaitu masuk gerbang tol Sukun dan keluar gerbang tol Gayamsari

Catatan: 
  • Semua bus melewati Tuntang, Bawen, Pasar Karangjati, Pasar Babadan, Banyumanik, dan Sukun, setelah dari sukun jalurnya baru berubah seperti rute masing-masing. 
  • Beberapa penjelasan dari artikel di atas belum lengkap, untuk itu silakan baca beberapa komentar  yang sudah ada sebagai pelengkapnya.

    Proposal Sponsor Buku

    Beberapa bulan belakangan ini saya bersama teman-teman sedang menulis buku Belajar Komputer Tingkat Dasar untuk anak-anak.

    Buku yang kami tulis tersebut terdiri dari 16 seri yaitu:
    • 4 (empat) buku untuk tingkat 0 (nol), yaitu ditujukan untuk murid TK kecil dan besar yang masing-masing untuk semester 1 dan 2.
    • 12 (dua belas) buku tingkat 1 sampai dengan 6, yaitu ditujukan untuk murid tingkat SD yang masing-masing untuk semester 1 dan 2.
     Dalam waktu dekat ini kami akan mulai merilisnya satu persatu.
    Seperti beberapa buku yang sudah saya rilis sebelumnya yang menggunakan sistem sponsor. Buku yang kami tulis ini juga menganut cara yang sama.
    Beberapa orang teman sudah menanyakan tata cara menjadi sponsor buku tersebut. Maka malalui post ini saya lampirkan tautan tata cara menjadi sponsor buku tersebut

    Unduh Proposal sponsor buku

    Demikian pemberitahuan tentang perkembangan Belajar Komputer Dasar yang kami tulis.