@naanlang/naan 1.4.2 → 1.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * column positioning: // // !
8
8
  *
9
- * Copyright (c) 2024 by Richard C. Zulch
9
+ * Copyright (c) 2024-2025 by Richard C. Zulch
10
10
  *
11
11
  */
12
12
 
@@ -22,61 +22,13 @@ vmState = false;
22
22
  */
23
23
 
24
24
  closure VmControl(local ycvm) {
25
- global(js, https, nodeHttp, vmState)
25
+ global(js, https, http, vmState)
26
26
  if vmState.ycvm
27
27
  return (vmState.ycvm) // singleton
28
28
  ycvm = new(object, this)
29
29
  vmState = new(nonce) // don't save with state
30
30
  vmState.ycvm = ycvm
31
31
 
32
- // httpLocalRequest
33
- //
34
- // Make a simple GET request for the Docker's 169.254.169.254 metadata interface. This is not
35
- // supported by the standard NaaN framework HttpsApiRequest because it is HTTP and returns JSON
36
- // without bothering to set a contentType advising this.
37
- //
38
-
39
- closure httpLocalRequest(url, params, local pending, chunks, request) {
40
- pending = new(nonce)
41
- chunks = []
42
- request = nodeHttp.request(url, params, closure (response) {
43
- response.on("data", function (chunk) {
44
- chunks.push(chunk)
45
- })
46
- response.on("end", function (local content, error) {
47
- content = js.g.Buffer.concat(chunks)
48
- if response.statusCode < 200 || response.statusCode >= 299 { // 299 is "cancelled"
49
- debuglog("httpRequest status:", url, response.statusCode, "message:", content)
50
- pending.signal(list(Error("httpRequest statusCode:", url, response.statusCode, {
51
- status: response.statusCode
52
- }), false, { status: response.statusCode }))
53
- return
54
- }
55
- if response.complete {
56
- try {
57
- content = js.g.JSON.parse(content.toString())
58
- } catch {
59
- error = Error("httpRequest decode:", url, exception)
60
- }
61
- }
62
- else
63
- error = Error("httpRequest terminated prematurely:", url, response.statusCode)
64
- pending.signal(list(error, content, {
65
- headers: response.headers
66
- status: response.statusCode
67
- contentType: response.headers["content-type"]
68
- }))
69
- })
70
- })
71
- request.on("error", function hre(error) {
72
- debuglog("httpRequest error:", url, "error:", error)
73
- error = Error("httpRequest failed:", url, error)
74
- pending.signal(list(error))
75
- })
76
- request.end()
77
- pending.wait()
78
- }
79
-
80
32
  // getIdentityDoc
81
33
  //
82
34
  // Ask the VM for its identity document. This information does not change.
@@ -89,10 +41,11 @@ closure VmControl(local ycvm) {
89
41
  closure getIdentityDoc(local error, idDoc) {
90
42
  if ycvm.idDoc
91
43
  return (list(false, ycvm.idDoc))
92
- `(error, idDoc) = httpLocalRequest("http://169.254.169.254/computeMetadata/v1/instance/vendor/identity/document", {
44
+ `(error, idDoc) = http.HttpRequest("http://169.254.169.254/computeMetadata/v1/instance/vendor/identity/document", {
93
45
  headers: {
94
46
  "Metadata-Flavor": "Google"
95
47
  }
48
+ json: true
96
49
  })
97
50
  if error
98
51
  list(error)
@@ -116,10 +69,11 @@ closure VmControl(local ycvm) {
116
69
  now = milliseconds()
117
70
  if ycvm.authDoc && ycvm.authDocExpire > milliseconds()
118
71
  return (list(false, ycvm.authDoc)) // use cached credential
119
- `(error, authDoc) = httpLocalRequest("http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token", {
72
+ `(error, authDoc) = http.HttpRequest("http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token", {
120
73
  headers: {
121
74
  "Metadata-Flavor": "Google"
122
75
  }
76
+ json: true
123
77
  })
124
78
  if authDoc {
125
79
  expireTime = now + (authDoc.expires_in - 3600) * 1000 // give us 1 hour of margin
@@ -135,7 +89,7 @@ closure VmControl(local ycvm) {
135
89
  else
136
90
  list(false, authDoc)
137
91
  }
138
-
92
+
139
93
  // authHeader
140
94
  //
141
95
  // Return authorization header for the VM to be used in API requests to YC, as a result tuple.
@@ -148,7 +102,42 @@ closure VmControl(local ycvm) {
148
102
  else
149
103
  list(false, list(`Authorization, "${authDoc.token_type} ${authDoc.access_token}"))
150
104
  }
151
-
105
+
106
+ // getHostname
107
+ //
108
+ // Ask the VM for its FQDN.
109
+ //
110
+ // curl -H Metadata-Flavor:Google 169.254.169.254/computeMetadata/v1/instance/hostname
111
+ // tutorbe-1.ru-central1.internal
112
+ //
113
+ ycvm.getHostname = closure getHostname(local error, hostname) {
114
+ `(error, hostname) = http.HttpRequest("http://169.254.169.254/computeMetadata/v1/instance/hostname", {
115
+ headers: [ list("Metadata-Flavor", "Google") ]
116
+ })
117
+ if error
118
+ list(error)
119
+ else
120
+ list(false, hostname)
121
+ }
122
+
123
+ // getUserData
124
+ //
125
+ // Ask the VM for its user-data configuration.
126
+ //
127
+ // curl -H Metadata-Flavor:Google 169.254.169.254/computeMetadata/v1/instance/hostname
128
+ // #cloud-config
129
+ // <...yaml...>
130
+ //
131
+ ycvm.getUserData = closure getUserData(local error, userData) {
132
+ `(error, userData) = http.HttpRequest("http://169.254.169.254/latest/user-data", {
133
+ headers: [ list("Metadata-Flavor", "Google") ]
134
+ })
135
+ if error
136
+ list(error)
137
+ else
138
+ list(false, userData)
139
+ }
140
+
152
141
  // shutdownVM
153
142
  //
154
143
  // Tell YC to shutdown our VM.
@@ -202,6 +191,7 @@ function ycvmInit(local manifest) {
202
191
  Naan.module.build(module.id, "yc_vm", function(modobj, compobj) {
203
192
  require("./serviceYC.nlg")
204
193
  compobj.manifest = manifest
194
+ http = require("naanlib:frameworks/node/http_request.nlg")
205
195
  module.exports.VmControl = VmControl
206
196
  })
207
197
  } ();
@@ -558,42 +558,11 @@ RegisterTestCategory("core", [
558
558
  [ "function testret x { loop { loop { return(77) } } };", "testret" ],
559
559
  [ "testret();", "77" ],
560
560
 
561
-
562
561
  //
563
- // objects
562
+ // dictionaries
564
563
  //
565
-
566
- [ "new();", "false" ],
567
- [ "testo=new(object);", "Object{0}" ],
568
- [ "testo.a=3;", "3" ],
569
- [ "testo;", "Object{1}" ],
570
- [ "testo.b=4;", "4" ],
571
- [ "b=a;", "a" ],
572
- [ "testo.b;", "4" ],
573
- [ "testo;", "Object{2}" ],
574
- [ "totuple(testo);>", "((\"a\" . 3) (\"b\" . 4))" ],
575
- [ "testo1=new(testo);", "Object{2}" ],
576
- [ "totuple(testo1);>", "((\"a\" . 3) (\"b\" . 4))" ],
577
- [ "testo1.b=5;", "5" ],
578
- [ "testo.b;", "4" ],
579
- [ "testo.\"b\";", "4" ],
580
- [ "xget(testo,\"b\");", "4" ],
581
- [ "xget(testo,b);", "3" ], // b has value `a, and test.a is 3
582
- [ "testo.f = function(x) { x+1 };>", "(function lambda (x) (+ x 1))" ],
583
- [ "testo.f(5);", "6" ],
584
- [ "apply(deref(testo, \"f\"), list(6));", "7" ],
585
-
586
- [ "testo.length = 5;", "5" ],
587
- [ "testo.length;", "5" ],
588
- [ "length(testo);", "4" ],
589
- [ "xget(testo, length);", "5" ],
590
- [ "xkeys(testo);>", "(\"a\" \"b\" \"f\" \"length\")" ],
591
- [ "totuple(testo);>", "((\"a\" . 3) (\"b\" . 4) (\"f\" function lambda (x) (+ x 1)) (\"length\" . 5))" ],
592
564
 
593
- [ "testo1.4=c;", "c" ],
594
- [ "testo1.4;", "c" ],
595
-
596
- [ "this = true;", { errors: "can't modify NaanCore::this from Test-core" } ],
565
+ [ "b=a;", "a" ], // testing eval here
597
566
 
598
567
  [ "joe={};", "{ }" ],
599
568
  [ "joe.sam=function(x) { print(x, \"|\", keys(joe)) };>", "(function lambda (x) (print x \"|\" (keys joe)))" ],
@@ -637,6 +606,46 @@ RegisterTestCategory("core", [
637
606
  ["merge(oo, list(1.0/3), {false:c});", "{ true: a, false: c }"],
638
607
  ["oo;", "{ true: a, 0.3333333333333333: b }"],
639
608
 
609
+ ["joe={a:3}; {b:joe} == {b:joe}", "{ a: 3 }|true"],
610
+ ["joe === joe", "true"],
611
+ ["{b:joe} === {b:joe}", "false"],
612
+
613
+
614
+ //
615
+ // objects
616
+ //
617
+
618
+ [ "new();", "false" ],
619
+ [ "testo=new(object);", "Object{0}" ],
620
+ [ "testo.a=3;", "3" ],
621
+ [ "testo;", "Object{1}" ],
622
+ [ "testo.b=4;", "4" ],
623
+ [ "testo.b;", "4" ],
624
+ [ "testo;", "Object{2}" ],
625
+ [ "totuple(testo);>", "((\"a\" . 3) (\"b\" . 4))" ],
626
+ [ "testo1=new(testo);", "Object{2}" ],
627
+ [ "totuple(testo1);>", "((\"a\" . 3) (\"b\" . 4))" ],
628
+ [ "testo1.b=5;", "5" ],
629
+ [ "testo.b;", "4" ],
630
+ [ "testo.\"b\";", "4" ],
631
+ [ "xget(testo,\"b\");", "4" ],
632
+ [ "xget(testo,b);", "3" ], // b has value `a, and test.a is 3
633
+ [ "testo.f = function(x) { x+1 };>", "(function lambda (x) (+ x 1))" ],
634
+ [ "testo.f(5);", "6" ],
635
+ [ "apply(deref(testo, \"f\"), list(6));", "7" ],
636
+
637
+ [ "testo.length = 5;", "5" ],
638
+ [ "testo.length;", "5" ],
639
+ [ "length(testo);", "4" ],
640
+ [ "xget(testo, length);", "5" ],
641
+ [ "xkeys(testo);>", "(\"a\" \"b\" \"f\" \"length\")" ],
642
+ [ "totuple(testo);>", "((\"a\" . 3) (\"b\" . 4) (\"f\" function lambda (x) (+ x 1)) (\"length\" . 5))" ],
643
+
644
+ [ "testo1.4=c;", "c" ],
645
+ [ "testo1.4;", "c" ],
646
+
647
+ [ "this = true;", { errors: "can't modify NaanCore::this from Test-core" } ],
648
+
640
649
  //
641
650
  // object getters/setters
642
651
  //
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * column positioning: // // !
8
8
  *
9
- * Copyright (c) 2020-2022 by Richard C. Zulch
9
+ * Copyright (c) 2020-2025 by Richard C. Zulch
10
10
  *
11
11
  */
12
12
 
@@ -135,8 +135,8 @@ RegisterTestCategory("JSinterop", [
135
135
  " print(\"in-\", x, \"-\", nthl.0)\n"
136
136
  " } }" ],
137
137
 
138
- [ "Array(0,1,2,3,4,5,6,7,8,9,10).filter(function&(nth) { stacktrap(nth,function&() { print(\"in-\",nth, \" \") }) });",
139
- { text: "in-0 in-1 in-nth in-nth in-nth in-nth in-nth in-nth in-nth in-nth in-nth" } ],
138
+ [ "Array(0,1,2,3,4,5,6,7,8,9,10).filter(closure(nth) { stacktrap(nth,function() { print('in-', nth, space) }) });",
139
+ { text: "in-0 in-1 in-2 in-3 in-4 in-5 in-6 in-7 in-8 in-9 in-10" } ],
140
140
 
141
141
  [ "loop { stacktrap(0,function&(x) { print(\"loop-\",x) }), break };", "loop-Dictionary{0}|{ }" ],
142
142
  [ "loop { stacktrap(1,function&(x) { print(\"loop-\",x) }), break };", "loop-Dictionary{0}|{ }" ],